Search code examples
c#xmlwinformsfilesystemwatcher

FileSystemWatcher Invalid data Exception error


enter image description here
I want to refresh my datagridview if there are changes in a particular xml file. I got a FileSystemWatcher to look for any changes in the file and call the datagirdview function to reload the xml data.

When i tried, i'm getting Invalid data Exception error Somebody please tell what is the mistake am i doing here??

  public Form1()
            {
                InitializeComponent();
                FileSystemWatcher watcher = new FileSystemWatcher();

                watcher.Path = @"C:\test";
                watcher.Changed +=  fileSystemWatcher1_Changed;
                watcher.EnableRaisingEvents = true;
                //watches only Person.xml
                watcher.Filter = "Person.xml";

                //watches all files with a .xml extension
                watcher.Filter = "*.xml";

            }

            private const string filePath = @"C:\test\Person.xml";
            private void LoadDatagrid()
            {
                try
                {
                    using (XmlReader xmlFile = XmlReader.Create(filePath, new XmlReaderSettings()))
                    {
                        DataSet ds = new DataSet();
                        ds.ReadXml(xmlFile);
                        dataGridView1.DataSource = ds.Tables[0]; //Here is the problem
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                } 
            }

            private void Form1_Load(object sender, EventArgs e)
            {
                LoadDatagrid();
            }

private void fileSystemWatcher1_Changed(object sender, FileSystemEventArgs e)
            {
                LoadDatagrid();
            }

Solution

  • This is because the FileSystemWatcher runs on a distinct thread, not the UI thread. On winforms apps only the UI thread - the main thread of the program - can interact with visual constrols. If you need to interact with visual controls from another thread - like this case - you must call Invoke on the target control.

     // this event will be fired from the thread where FileSystemWatcher is running.
     private void fileSystemWatcher1_Changed(object sender, FileSystemEventArgs e)
     {
          // Call Invoke on the current form, so the LoadDataGrid method
          // will be executed on the main UI thread.
          this.Invoke(new Action(()=> LoadDatagrid()));
     }