18

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

现在,当我在一个单元格中单击两次时,它将打开以进行编辑。

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

EndEdit 也被调用了两次,但总是针对选定的项目,而不是错误的项目。

这是一个已知问题吗?仅获得(正确的)一个通知的任何解决方法。

4

4 回答 4

24

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

问题似乎是有两件事都认为他们负责IEditableObject国家。当 WPF 提供默认的集合视图时,它会IEditableObject在集合中的对象上查找,并调用BeginEdit和响应对相应EndEdit方法的调用。而且,将调用方法以响应对and or的调用。CancelEditIEditableCollectionViewBindingGroupIEditableObjectBeginEditCommitEditCancelEdit

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

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

您在 Toolkit 中没有看到网格存在此问题的原因是它似乎是一个稍旧的版本 - 将其中的代码与 Reflector 为 .NET 4.0 显示的代码进行比较,您会发现 .NET 4.0DataGrid具有一些额外的代码(一个新的方法,EnsureItemBindingGroup和一些相关的代码在MeasureOverrideand中OnRowValidationRulesChanged)确保绑定组总是存在,不管你是否要求它。因此,如果 WPF 工具包被更新,它可能会增加一个类似的功能,除非这个问题得到修复。(我猜想,如果您使用 WPF Toolkit 的当前版本(我写这篇文章时是 2010 年 2 月),并且您使用该ItemBindingGroup属性明确要求绑定组,您会看到完全相同的问题。)

BeginEdit正如您所描述的,这并没有解释如何调用随机对象。我无法重现。但它确实解释了对所选对象的双重调用。最好的办法似乎是对源对象进行编码,以便它们能够容忍双重调用。

于 2011-01-03T14:53:04.340 回答
4

我不确定在 BeginEdit 事件发生之前你会用什么来中断它,但是对于 EndEdit 来说,一个简单的 isDirty 标记就可以了。在实现 IEditableObject 的 Entity 类中,添加以下内容:

    private bool _isDirty = false;

    #region IEditableObject Members

    public void BeginEdit()
    {
        // Bug Fix: Windows Controls call EndEdit twice; Once
        // from IEditableCollectionView, and once from BindingGroup.
        // This makes sure it only happens once after a BeginEdit.
        _isDirty = true;
    }

    public void CancelEdit() { }

    public void EndEdit()
    {
        if (ItemEndEdit != null && _isDirty)
        {
            _isDirty = false;
            ItemEndEdit(this);
        }
    }

    #endregion
于 2013-06-19T11:04:55.333 回答
3

我在使用 .NET Framework 4 DataGrid 时遇到了同样的问题。

添加对 WPFToolkit 最新版本的引用

添加

xmlns:dg="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"

<DataGrid>并改变<dg:DataGrid>

于 2010-12-17T14:10:21.487 回答
1

+1 @IanGriffiths 用于诊断问题。至于解决方案(或解决方法),您可以计算“待处理”编辑的数量。这意味着类似:

void BeginEdit()
{
    _numEdits++;
}

void CancelEdit()
{
    if(--_numEdits < 0)
        throw new Exception("WTF?"); 
}

void EndEdit()
{
    CancelEdit();
    if(_numEdits == 0)
        commitEdit();
}
于 2014-05-12T13:44:23.367 回答