0

Hi
developing a video application which is almost complete and just getting rid of a few bugs, one i am stuck on is an auto updating list box

i use filesystemwatcher to update contents of listbox and added a bit of code with a textbox to allow me to change the name of listbox item i click on, this works great apart from when i am editing the filename and the listbox updates at same time as this causes the selected index to change so it crashes my application, i guess i need to hold selecteditem value until i finish editing name but i'm at loss at how to do this

I thought about using a lock but not sure if that would stop the listbox updating as well and i was thinking about a using a Variable to store selected index but cant work out how to do this

using vs2008 c#

private void fileSystemWatcher1_Created(object sender, System.IO.FileSystemEventArgs e) 
        { 
 
             
            listBox1.Items.Add(e.FullPath); 
            listBox1.SelectedIndex = listBox1.Items.Count - 1; 
            listBox1.SelectedIndex = -1; 
                    } 
 
        private void listBox1_Click(object sender, EventArgs e) 
        { 
            
            int itemSelected = this.listBox1.SelectedIndex; 
            string itemText = this.listBox1.Items[itemSelected].ToString(); 
 
            Rectangle r = this.listBox1.GetItemRectangle(itemSelected); 
            this.textBox1.Location = new System.Drawing.Point(r.X + 563, r.Y + 569); 
            this.textBox1.Size = new System.Drawing.Size(r.Width + 4, r.Height - 10); 
            this.textBox1.Visible = true; 
            this.textBox1.Text = itemText; 
            this.textBox1.Focus(); 
            this.textBox1.SelectAll(); 
         
        } 
 
        
        private void textBox1_KeyPress(object sender, KeyPressEventArgs e) 
        { 
             
             
            if (e.KeyChar == 13) 
             
            { 
                
                this.listBox1.Items[this.listBox1.SelectedIndex] = this.textBox1.Text; 
                 
                this.textBox1.Visible = false; 
                 
                 
 
            } 
            if (e.KeyChar == 27) 
                this.textBox1.Visible = false;
2
Contributors
6
Replies
7
Views
6 Years
Discussion Span
Last Post by kenny22
0

All you need is to make

itemSelected

variable global in that class.

Here's a one way to do it. I used a separate textbox for renaming. I suppose you're doing some kind of "inplace" renaming?

// A global variable to hold index of the renamed listbox item
private int _selectedItemIndex;

// I used changed event to trap changes. Of course you have to fill the listbox first
private void fileSystemWatcher1_Changed(object sender, FileSystemEventArgs e)
{
    // Check if the name exists -> no duplicates
    if (!listBox1.Items.Contains(e.FullPath))
    {
        listBox1.Items.Add(e.FullPath);
        listBox1.SelectedIndex = listBox1.Items.Count - 1;
    }
    // listBox1.SelectedIndex = -1; ???
}

// private void fileSystemWatcher1_Created(object sender, System.IO.FileSystemEventArgs e) 
// { 
//     listBox1.Items.Add(e.FullPath); 
//     listBox1.SelectedIndex = listBox1.Items.Count - 1; 
//     listBox1.SelectedIndex = -1; 
// } 

private void listBox1_Click(object sender, EventArgs e) 
{ 
    // Use global _selectedItemIndex instead of the procedure local variable
    
    // int itemSelected = this.listBox1.SelectedIndex; 
    _selectedItemIndex = this.listBox1.SelectedIndex; 

    // string itemText = this.listBox1.Items[itemSelected].ToString(); 
    string itemText = this.listBox1.Items[_selectedItemIndex].ToString(); 

    // Rectangle r = this.listBox1.GetItemRectangle(itemSelected); 
    
    // I had to comment this code out and used a separate textbox for renaming
    //Rectangle r = this.listBox1.GetItemRectangle(_selectedItemIndex); 
    //this.textBox1.Location = new System.Drawing.Point(r.X + 563, r.Y + 569); 
    //this.textBox1.Size = new System.Drawing.Size(r.Width + 4, r.Height - 10); 
    this.textBox1.Visible = true; 
    this.textBox1.Text = itemText; 
    this.textBox1.Focus(); 
    this.textBox1.SelectAll(); 
}

private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
    if (e.KeyChar == 13)
    {
        // Check before renaming if the file exists? Can't create a duplicate filename
        if (!File.Exists(this.textBox1.Text))
        {
            string _FileName;

            // Check that filename i.e. this.textBox1.Text is a valid filename!!!
            // no code for that :)

            // Save the current name
            _FileName = this.listBox1.Items[_selectedItemIndex].ToString();
            // Remove item from the list
            this.listBox1.Items.RemoveAt(_selectedItemIndex);
            // Rename the file. Notice: This triggers fileSystemWatcher1_Changed event and the item is added to the listbox again with a new name!
            File.Move(_FileName, this.textBox1.Text);
        }

        // this.listBox1.Items[this.listBox1.SelectedIndex] = this.textBox1.Text;

        _selectedItemIndex = -1; // Nothing is selected
        this.textBox1.Visible = false;
    }
    if (e.KeyChar == 27)
        this.textBox1.Visible = false;
}

You may have to do some modifications to the code, like I had to do in your code. But I hope you'll get the idea how to rename the file and still maintain the listbox's content.

HTH

0

Thanks for the help
my code ends up as below and works fine, however i now need to add code to check for duplicate filename and a way to stop me selecting and renaming a file that is still being written to.

my project records video to a new file every 60 seconds so if i try and rename a file when its still being written to then my project crashes

private int _selectedItemIndex;

        private void fileSystemWatcher1_Created(object sender, System.IO.FileSystemEventArgs e)
        {
            listBox1.Items.Add(e.FullPath);
            listBox1.SelectedIndex = listBox1.Items.Count - 1;
            listBox1.SelectedIndex = -1;
        }

        private void listBox1_Click(object sender, EventArgs e)
        {

             _selectedItemIndex = this.listBox1.SelectedIndex; 

            string itemText = this.listBox1.Items[_selectedItemIndex].ToString();

            this.textBox1.Visible = true;
            this.textBox1.Text = itemText;
            this.textBox1.Focus();
            this.textBox1.SelectAll();

        }


        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {


            if (e.KeyChar == 13)
            {
                // Check before renaming if the file exists? Can't create a duplicate filename 
                if (!File.Exists(this.textBox1.Text))  //Doesnt work    
                {            string _FileName;             
                    
                    _FileName = this.listBox1.Items[_selectedItemIndex].ToString(); 
                    // Remove item from the list 
                    this.listBox1.Items.RemoveAt(_selectedItemIndex); 
                    // Rename the file. Notice: This triggers fileSystemWatcher1_Changed event and the item is added to the listbox again with a new name! 
                    File.Move(_FileName, "c:\\Replay\\" + this.textBox1.Text + ".avi");
                }  
                // this.listBox1.Items[this.listBox1.SelectedIndex] = this.textBox1.Text;
                _selectedItemIndex = -1; // Nothing is selected 
                 this.textBox1.Visible = false;


             

              

            } 
            if (e.KeyChar == 27)
                this.textBox1.Visible = false;



        }
0

There was already check for duplicates:

// Check if the name exists -> no duplicates
if (!listBox1.Items.Contains(e.FullPath))
{
  listBox1.Items.Add(e.FullPath);
  listBox1.SelectedIndex = listBox1.Items.Count - 1;
  listBox1.SelectedIndex = -1;
}

To prevent "crashes" you use try...catch...finally blocks:

// Rename the file
try
{
  File.Move(_FileName, this.textBox1.Text);
  // Remove item from the list (if File.Move() didn't threw an exception)
  this.listBox1.Items.RemoveAt(_selectedItemIndex);
}
catch (Exception)
{
  // Catch the exception (assuming 'file is open' exception)
  // This simply "cancels" renaming
}
0

Many thanks Guys, 1 day to solve a problem thats been doing my head in for weeks. Good easy to understand replies.

i sorted out duplicate file name it was just a case of pointing to correct directory which i missed due to tiredness.

added the exception and works like a dream. 1 minor thing i would like to fix
i notice i get a beep when i press enter to add new text, is there a way to stop this


My code to help others

private int _selectedItemIndex;

        private void fileSystemWatcher1_Created(object sender, System.IO.FileSystemEventArgs e)
        {
            listBox1.Items.Add(e.FullPath);
            listBox1.SelectedIndex = listBox1.Items.Count - 1;
            listBox1.SelectedIndex = -1;
        }

        private void listBox1_Click(object sender, EventArgs e)
        {

             _selectedItemIndex = this.listBox1.SelectedIndex; 
// added a catch to stop error when clicking on listbox with no entries in it
  try
            {
                string itemText = this.listBox1.Items[_selectedItemIndex].ToString();
           

            this.textBox1.Visible = true;
            this.textBox1.Text = itemText;
            this.textBox1.Focus();
            this.textBox1.SelectAll();
            }
            catch (ArgumentOutOfRangeException)
            {
            }
        }


        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {


            if (e.KeyChar == 13)
            {
                // Check before renaming if the file exists? Can't create a duplicate filename 
                if (!File.Exists("c:\\Replay\\" +this.textBox1.Text +".avi"))      
                {            string _FileName;            

                    // Save the current name  
                    
                    _FileName = this.listBox1.Items[_selectedItemIndex].ToString(); 
                    // Remove item from the list 

                    try
                    {
                        File.Move(_FileName, "c:\\Replay\\" + this.textBox1.Text + ".avi");
                        this.listBox1.Items.RemoveAt(_selectedItemIndex);
                         
                        
                    }
                    catch (Exception)
                    {
                    }
                }  
                
                _selectedItemIndex = -1; // Nothing is selected 
                 this.textBox1.Visible = false;


              

            } 
            if (e.KeyChar == 27)
                this.textBox1.Visible = false;

Edited by kenny22: n/a

0

i notice i get a beep when i press enter to add new text, is there a way to stop this

That's a system sound coming from an unhandled keypress.

But since you do handle keystrokes in your code, you have to notify system that a keypress is actually handled (no need to beep). Add a one more line of code:

LINE:
58. _selectedItemIndex = -1; // Nothing is selected
59. this.textBox1.Visible = false;
60. e.Handled = true; // <- Tell the system that the keypress has been handled
0

Once again quick easy to understand replies
problem solved in space of a few days

many thanks for the help on here hopefully i can return the favour to others in future

kenny

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.