WPF DataGrid在IEditableObject上调用BeginEdit两次? [英] WPF DataGrid calls BeginEdit on an IEditableObject two times?
问题描述
我有一个DataGrid绑定到IEditableObject的集合。
现在,当我在单元格中单击两次时,它将被打开进行编辑。 p>
有趣的是:BeginEdit将被调用两次。有时候对于相同的EditableObject,但有时候两个不同的对象(特别是当我使用PgDn直到我打到DataGrid的结尾),正确的一个将被首先调用,然后从集合中的一些其他项目,从未在焦点之前
EndEdit也被调用两次,但总是为所选项目调用,而不是错误的。
如果您在调试器中查看堆栈跟踪 BeginEdit
被调用,你会看到第一次,它是收集视图调用它,而第二次,它是一个 BindingGroup
。
问题似乎是有两件事情都认为他们负责$ code> IEditableObject 状态。当WPF提供默认集合视图时,它将在集合中的对象上查找 IEditableObject
,并调用 BeginEdit
并且 EndEdit
或 CancelEdit
以响应对相应的 IEditableCollectionView
方法。但是, BindingGroup
将调用 IEditableObject
方法来响应调用 BeginEdit
和 CommitEdit
或 CancelEdit
。
DataGrid
使用这两个功能:当您连续开始和完成编辑时,它会通知 IEditableCollectionView
和 BindingGroup
,并且这两个事情都认为这是他们的责任,继续下去并通知 IEditableObject
code code code code code code code code code code code code $两个不同的对象调用 BeginEdit
(和相关方法)。这是因为它使用可编辑的集合视图和绑定组 - 从它的外观,那些不被设计为在同一对象上同时使用,方式是 DataGrid
使用它们。
工具包中没有看到网格的这个问题的原因是它似乎是一个较旧的版本 - 将代码与Reflector显示为.NET 4.0的代码进行比较,您将看到.NET 4.0 DataGrid
具有一些额外的代码(一种新方法, EnsureItemBindingGroup
,以及 MeasureOverride
和 OnRowValidationRulesChanged
中的一些相关代码,确保绑定组始终存在,无论是否要求。所以如果WPF工具包被更新,它可能会增长一个类似的功能,除非这是固定的。 (如果您在WPF工具包中使用当前版本 - 2010年2月,请使用 ItemBindingGroup
属性显式询问绑定组,你会看到完全相同的问题。)
这不解释如何调用$ code BeginEdit 在你所描述的随机对象上。我不能这样做。但它确实解释了所选对象的双重调用。最好的事情似乎是为了对源对象进行编码,以便允许双重呼叫。
I've got a DataGrid bound to a collection of IEditableObject's.
Now when I click two times in a cell, it will be opened for editing.
Funny thing is: BeginEdit will be called two times. Sometimes for the same EditableObject, but sometimes for two different objects (especially when I use PgDn until I hit the end of the DataGrid) the correct one will be called first, then some other item from the collection, which never had been in focus before.
EndEdit is called twice, too, but always for the selected Item, not for the wrong one.
Is this a known problem? Any workarounds to get only (the right) one notification.
If you look at the stack trace in the debugger when BeginEdit
is called, you'll see that the first time, it's the collection view calling it, and the second time, it's a BindingGroup
.
The problem appears to be that there are two things that both think they are in charge of the IEditableObject
state. When WPF provides a default collection view, it will look for IEditableObject
on the objects in the collection, and will call BeginEdit
and either EndEdit
or CancelEdit
in response to calls to the corresponding IEditableCollectionView
methods. But also, the BindingGroup
will call the IEditableObject
methods in response to calls to BeginEdit
and CommitEdit
or CancelEdit
.
The DataGrid
uses both features: when you start and complete edits in a row, it notifies the IEditableCollectionView
and the BindingGroup
and both of those things think that it's their responsibility in turn to go on and notify the IEditableObject
implementation on the underlying source object.
So it looks rather like a bug in the DataGrid
- it causes two different objects to call BeginEdit
(and related methods). And it's because it makes use of editable collection views and binding groups - from the look of it, those weren't designed to be used at the same time on the same objects, in the way that the DataGrid
uses them.
The reason you don't see this problem with the grid in the Toolkit is that it appears to be a slightly older version - comparing the code in that with what Reflector shows for .NET 4.0, you'll see that the .NET 4.0 DataGrid
has some extra code (a new method, EnsureItemBindingGroup
, and some related code in MeasureOverride
and OnRowValidationRulesChanged
) that ensures that a binding group always exists, whether you ask for it or not. So if the WPF Toolkit is updated, it'll probably grow a similar feature unless this gets fixed. (And I would guess that if you use the current edition - February 2010 as I write this - of the WPF Toolkit, and you use the ItemBindingGroup
property to ask explicitly for a binding group, you'd see exactly the same problem.)
This doesn't explain how you'd get calls to BeginEdit
on random objects as you've described. I can't repro that. But it does explain double calls on the selected object. The best thing to do appears to be to code your source objects so that they will tolerate the double calls.
这篇关于WPF DataGrid在IEditableObject上调用BeginEdit两次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!