Search code examples
c#.netwinformsfilesystemwatcher

Multiple FileSystem watcher with multiple listbox control


I'm trying to make a monitoring page to monitor various filesystem watcher running to do some job. What I need to know is how do you get multiple filesystem watcher's to access the list boxes in the UI thread.. Here is some code:

private void WatchFile(TextBox ctrlTB,ListBox ctrlLB,FileSystemWatcher _watcher)
    {
        // FileSystemWatcher _watcher = new FileSystemWatcher();
        //var localTB = ctrlTB as TextBox;
        //var localLB = ctrlLB as ListBox;
        _watcher.Path = ctrlTB.Text;
        _watcher.Path = ctrlTB.Text; 



        _watcher.NotifyFilter = NotifyFilters.LastWrite;
        _watcher.Filter = "*.xml";

        _watcher.Changed += new FileSystemEventHandler(convertXML);
       // _watcher.Changed += (s, e) => convertXML(s,e); 
       // _watcher.Error += new ErrorEventHandler(WatcherError);
        _watcher.EnableRaisingEvents = true;
        _watcher.IncludeSubdirectories = false;


        ctrlLB.Items.Add("Started Monitoring @ " + ctrlTB.Text);
        ctrlLB.SelectedIndex = ctrlLB.Items.Count - 1;
    }

public void convertXML(object source, FileSystemEventArgs f)
{
  /// some job
}

I need to post back the status for each filesystemwatcher back to it's respective listbox. I'm declaring the FSW's at the click of the start button. Every List box has a start button where it would be declared separately. An e.g.:

private void button9_Click(object sender, EventArgs e)
    {
        if (!Directory.Exists(this.textBox1.Text))
        {
            //Form2.ActiveForm.Text = "Please select Source Folder";
            // popup.Show("Please Select Source Folder");
            MessageBox.Show("Please Select Proper Source Folder");
            return;
        }

        else
        {
            textBox1.Enabled = false;

            button9.Enabled = false;
            button1.Enabled = false;
          //  button4.Enabled = false;
            FileSystemWatcher _watcher = new FileSystemWatcher();
            _watcher.SynchronizingObject = this;
           WatchFile(textBox1,listBox1 ,_watcher);
        }
    }

How does the thread know which contrl listbox to access.


Solution

  • Encapsulate your WatchFile and convertXml into its own class like so

    public class MyFileWatcher {
       private TextBox _textBox;
       private ListBox _listBox;
       FileSystemWatcher _watcher;
    
       public MyFileWatcher(TextBox textBox, ListBox listBox, ISynchronizeInvoke syncObj) {
           this._textBox = textBox;
           this._listBox = listBox;
    
           this._watcher = new FileSystemWatcher();
           this._watcher.SynchronizingObject = syncObj;
           this._watcher.Path = textBox.Text;
           this._watcher.Changed += new FileSystemEventHandler(convertXML);
           this._watcher.EnableRaisingEvents = true;
           this._watcher.IncludeSubdirectories = false;
    
           // add any other required initialization of the FileSystemWatcher here. 
       }
    
       protected virtual void convertXML(object source, FileSystemEventArgs f) {
           // interact with this._textBox and this._listBox here as required.
           // e.g.
           // this._listBox.Items.Add(f.FullPath);
       }
    }
    

    This way you can tie the FileSystemWatcher instance to a particular TextBox and ListBox, or any other object you desire.

    Then to replace your button9_Click method:

    private void button9_Click(object sender, EventArgs e)
    {
        if (!Directory.Exists(this.textBox1.Text))
        {
            //Form2.ActiveForm.Text = "Please select Source Folder";
            // popup.Show("Please Select Source Folder");
            MessageBox.Show("Please Select Proper Source Folder");
            return;
        }
    
        else
        {
            textBox1.Enabled = false;
    
            button9.Enabled = false;
            button1.Enabled = false;
    
            // instantiate your new instance of your MyFileWatcher class.
            MyFileWatcher myWatcher = new MyFileWatcher(textBox1,listBox1 ,this);
        }
    }
    

    Note: I have not actually compiled or executed this code so there may be exceptions. But the overall pattern should solve what you're after.