1

ここに画像の説明を入力
特定の xml ファイルに変更がある場合、datagridview を更新したいと考えています。FileSystemWatcher を使用してファイル内の変更を探し、datagirdview 関数を呼び出して xml データをリロードしました。

私が試したとき、私はInvalid data Exception error誰かが私がここでやっている間違いは何ですか??

  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();
            }
4

2 に答える 2

2

これは、FileSystemWatcherが UI スレッドではなく、個別のスレッドで実行されるためです。Winforms アプリでは、UI スレッド (プログラムのメイン スレッド) のみがビジュアル コントロールと対話できます。この場合のように、別のスレッドからビジュアル コントロールを操作する必要がある場合はInvoke、ターゲット コントロールを呼び出す必要があります。

 // 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()));
 }
于 2012-08-11T14:00:54.673 に答える
1

FileSystemWatcher は、UI スレッドではなく別のスレッドで実行されています。スレッド セーフを維持するために、.NET では非 UI スレッド (つまり、フォーム コンポーネントを作成したスレッド) から UI を更新できないようにしています。

問題を簡単に解決するには、対象のフォームの MethodInvoker メソッドを fileSystemWatcher1_Changed イベントから呼び出します。これを行う方法の詳細については、MethodInvoker Delegateを参照してください。これを行う方法には、他にもオプションがあります。イベントの結果/フラグを保持するための同期 (つまり、スレッドセーフ) オブジェクトをセットアップしますが、フォーム コードを変更する必要はありません (つまり、ゲームの場合、メイン ゲーム ループなどで同期オブジェクトをポーリングするだけで済みます)。 )。

private void fileSystemWatcher1_Changed(object sender, FileSystemEventArgs e)
{
    // Invoke an anonymous method on the thread of the form.
    this.Invoke((MethodInvoker) delegate
    {
        this.LoadDataGrid();
    });
}

編集: デリゲート内で問題があった以前の回答を修正しました。LoadDataGrid にはこれがありませんでした。そしてそれはそのように解決しません。

于 2012-08-11T13:58:26.417 に答える