如果特定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();
}
答案 0 :(得分: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()));
}
答案 1 :(得分:1)
FileSystemWatcher在单独的线程中运行,而不是在UI线程中运行。为了保持线程安全,.NET阻止您从非UI线程(即创建Form组件的线程)更新UI。
要轻松解决此问题,请从fileSystemWatcher1_Changed事件中调用目标Form的MethodInvoker方法。有关如何执行此操作的详细信息,请参阅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错过了这个。并且它不会这样解决。