我在WPF中使用DataGridView。 在RowEditEnding事件中,我获取旧行(编辑结束前),然后通过调度程序调用方法获取新行(编辑后)
private void myGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
{
DataRowView oldRowView = e.Row.Item as DataRowView;
DataRow oldRow = oldRowView.Row;
//When I put a breakpoint before the dispatcher is called, oldRow has the old row values.
Dispatcher.BeginInvoke(new Action(() => OnRowEdit(oldRow, e)), System.Windows.Threading.DispatcherPriority.Background);
//I have now passed the old row to OnRowEdit
}
void OnRowEdit(DataRow oldRow, DataGridRowEditEndingEventArgs e)
{
//Here oldRow has new row values.
}
在调用方法之前oldRow的item数组和调用方法之后的数组不匹配。这背后的原因是什么?
答案 0 :(得分:1)
如果没有a good, minimal, complete code example,就无法确定您的方案中存在什么问题。这里没有足够的背景。
但最有可能的是,你只是遇到了一个时间问题。也就是说,BeginInvoke()
调用的委托是异步执行的,稍后会在某些不确定的时间执行。因为它排队等待执行,所以几乎肯定会在行更新后执行,因此在执行方法时会看到新值。
可能的解决方案包括:
Invoke()
方法代替BeginInvoke()
。这是同步执行的,确保在调用OnRowEdit()
方法时未修改行对象。BeginInvoke()
之前将它们提取到一个临时对象(例如一个新数组)中并传递那个对象而不是行对象本身OnRowEdit()
。缺乏完整的代码示例,不清楚为什么要使用BeginInvoke()
;通常,用户编辑操作发生在调度程序线程中,因此可以直接访问UI对象,而无需调用Invoke()
或BeginInvoke()
。请注意,这与#1实际上是相同的选项...使用Invoke()
可能只是多余的。如果上述选项都不适合您,请通过提供一个好的代码示例来解决问题,首先解释一下您使用BeginInvoke()
的原因,以及为什么这些建议都不适用于您的情况。
答案 1 :(得分:0)
Peter Duniho说要回答你的确切问题。但是"正确"在我看来,这样做的方法是使用ViewModel。然后你会得到一份" old"并且可以验证" new"这会解决你的问题(我想?)。您可以对发生的事情有更多的全面控制,MVVM还有许多其他好处。