为什么当我传递参数时调度程序会这样?
Why is the dispatcher behaving this way when I pass a parameter?
我在 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的项目数组和调用方法后的数组不匹配。这背后的原因可能是什么?
没有 a good, minimal, complete code example,就无法确定您的场景中的问题所在。这里的上下文不够。
但很可能,您只是 运行 遇到了时间问题。也就是说,由 BeginInvoke()
调用的委托是异步执行的,稍后会在某个不确定的时间执行。由于它已排队等待执行,因此几乎肯定会在行更新发生后执行,因此您会在执行方法时看到新值。
可能的解决方案包括:
- 使用
Invoke()
方法代替 BeginInvoke()
。这是同步执行的,确保在调用 OnRowEdit()
方法时未修改行对象。
- 如果您只需要行中的值,请在调用
BeginInvoke()
之前将这些值提取到临时对象(例如新数组)中,然后传递 that 对象行对象本身。
- 直接调用
OnRowEdit()
即可。缺少完整的代码示例,根本不清楚为什么要使用 BeginInvoke()
;通常,用户编辑操作发生在调度程序线程中,因此可以直接访问 UI 对象,而无需调用 Invoke()
或 BeginInvoke()
。请注意,这实际上与 #1 相同的选项……使用 Invoke()
可能只是多余的。
如果上述选项中的 none 适合您,请通过包含一个好的代码示例来改进问题,解释您为什么首先使用 BeginInvoke()
,以及为什么 none 这些建议适用于您的情况。
Peter Duniho 所说的内容回答了您的确切问题。但在我看来,"correct" 这样做的方法是使用 ViewModel。然后您将拥有 "old" 的副本并可以验证 "new" 这将解决您的问题(我认为?)。您可以更全面地控制所发生的事情,并且 MVVM 也有许多其他好处。
我在 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的项目数组和调用方法后的数组不匹配。这背后的原因可能是什么?
没有 a good, minimal, complete code example,就无法确定您的场景中的问题所在。这里的上下文不够。
但很可能,您只是 运行 遇到了时间问题。也就是说,由 BeginInvoke()
调用的委托是异步执行的,稍后会在某个不确定的时间执行。由于它已排队等待执行,因此几乎肯定会在行更新发生后执行,因此您会在执行方法时看到新值。
可能的解决方案包括:
- 使用
Invoke()
方法代替BeginInvoke()
。这是同步执行的,确保在调用OnRowEdit()
方法时未修改行对象。 - 如果您只需要行中的值,请在调用
BeginInvoke()
之前将这些值提取到临时对象(例如新数组)中,然后传递 that 对象行对象本身。 - 直接调用
OnRowEdit()
即可。缺少完整的代码示例,根本不清楚为什么要使用BeginInvoke()
;通常,用户编辑操作发生在调度程序线程中,因此可以直接访问 UI 对象,而无需调用Invoke()
或BeginInvoke()
。请注意,这实际上与 #1 相同的选项……使用Invoke()
可能只是多余的。
如果上述选项中的 none 适合您,请通过包含一个好的代码示例来改进问题,解释您为什么首先使用 BeginInvoke()
,以及为什么 none 这些建议适用于您的情况。
Peter Duniho 所说的内容回答了您的确切问题。但在我看来,"correct" 这样做的方法是使用 ViewModel。然后您将拥有 "old" 的副本并可以验证 "new" 这将解决您的问题(我认为?)。您可以更全面地控制所发生的事情,并且 MVVM 也有许多其他好处。