WPF DataGrid 在 IEditableObject 上调用 BeginEdit 两次? [英] WPF DataGrid calls BeginEdit on an IEditableObject two times?

查看:18
本文介绍了WPF DataGrid 在 IEditableObject 上调用 BeginEdit 两次?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个绑定到 IEditableObject 集合的 DataGrid.

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.

有趣的是:BeginEdit 会被调用两次.有时对于同一个 EditableObject,但有时对于两个不同的对象(特别是当我使用 PgDn 直到我到达 DataGrid 的末尾时)首先会调用正确的一个,然后是集合中的其他一些项目,这些项目以前从未成为焦点.

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 也被调用两次,但总是针对选定的项目,而不是错误的项目.

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.

推荐答案

如果在调用 BeginEdit 时查看调试器中的堆栈跟踪,您会看到第一次,它是集合视图调用它,第二次,它是一个 BindingGroup.

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.

问题似乎是有两件事都认为他们负责 IEditableObject 状态.当 WPF 提供默认集合视图时,它将在集合中的对象上查找 IEditableObject,并调用 BeginEditEndEditCancelEdit 以响应对相应 IEditableCollectionView 方法的调用.而且,BindingGroup 将调用 IEditableObject 方法以响应对 BeginEditCommitEdit 的调用取消编辑.

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.

DataGrid 使用这两个功能:当您开始并完成连续编辑时,它会通知 IEditableCollectionView BindingGroup 并且这两者都认为他们有责任继续并通知底层源对象上的 IEditableObject 实现.

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.

所以它看起来更像是DataGrid 中的一个错误——它导致两个不同的对象调用BeginEdit(和相关方法).这是因为它使用了可编辑的集合视图和绑定组——从它的外观来看,它们并不是被设计为在同一对象上同时使用的,就像 DataGrid使用它们.

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.

您在 Toolkit 中没有看到网格出现此问题的原因是它似乎是一个稍旧的版本 - 将其中的代码与 Reflector 为 .NET 4.0 显示的代码进行比较,您会看到 .NET 4.0 DataGrid 有一些额外的代码(一个新方法,EnsureItemBindingGroup,以及一些在 MeasureOverrideOnRowValidationRulesChanged 中的相关代码) 确保绑定组始终存在,无论您是否要求.因此,如果 WPF Toolkit 被更新,除非得到修复,否则它可能会增加类似的功能.(而且我猜想,如果您使用 WPF Toolkit 的当前版本 - 2010 年 2 月 - 并且您使用 ItemBindingGroup 属性明确要求绑定组,您会看到完全一样的问题.)

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.)

这并没有解释您如何像您所描述的那样在随机对象上获得对 BeginEdit 的调用.我不能重复那个.但它确实解释了对所选对象的双重调用.最好的办法似乎是对您的源对象进行编码,以便它们能够容忍双重调用.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆