18

IEditableObject のコレクションにバインドされた DataGrid があります。

セルを 2 回クリックすると、編集用に開かれます。

面白いことに、BeginEdit は 2 回呼び出されます。同じ EditableObject の場合もあれば、2 つの異なるオブジェクトの場合もあります (特に、DataGrid の最後に到達するまで PgDn を使用する場合) 正しいオブジェクトが最初に呼び出され、次にコレクションから別のアイテムが呼び出されます。 .

EndEdit も 2 回呼び出されますが、間違ったアイテムではなく、常に選択されたアイテムに対して呼び出されます。

これは既知の問題ですか? (正しい) 1 つの通知のみを取得するための回避策。

4

4 に答える 4

24

が呼び出されたときにデバッガーでスタック トレースをBeginEdit見ると、1 回目はそれを呼び出すコレクション ビューであり、2 回目はBindingGroup.

問題は、両者が国家を担当していると考えていることが 2 つあることですIEditableObjectIEditableObjectWPF が既定のコレクション ビューを提供する場合、コレクション内のオブジェクトを検索し、対応するメソッドへの呼び出しに応答して、またはBeginEditいずれかを呼び出します。また、 はandまたはの呼び出しに応答してメソッドを呼び出します。EndEditCancelEditIEditableCollectionViewBindingGroupIEditableObjectBeginEditCommitEditCancelEdit

DataGrid両方の機能を使用します。連続して編集を開始して完了するIEditableCollectionView 、と に通知し、これらの両方が、基になるソース オブジェクトBindingGroupの実装に順番に進み、通知する責任があると考えます。IEditableObject

DataGridしたがって、これは 2 つの異なるオブジェクトBeginEdit(および関連するメソッド)を呼び出すバグのように見えます。これは、編集可能なコレクション ビューとバインディング グループを使用するためです。一見すると、これらは が使用するように、同じオブジェクトで同時に使用するようには設計されていませんDataGrid

Toolkit のグリッドでこの問題が見られない理由は、それが少し古いバージョンであるように見えるためです。.NET 4.0 の Reflector が示すコードとそのコードを比較すると、.NET 4.0DataGridには要求するかどうかに関係なく、バインディング グループが常に存在することを保証する追加のコード (新しいメソッド、 、およびおよびEnsureItemBindingGroupの関連コード)。したがって、WPF ツールキットが更新された場合、これが修正されない限り、おそらく同様の機能が拡張されるでしょう。(そして、これを書いている 2010 年 2 月現在の WPF ツールキットを使用し、プロパティを使用してバインディング グループを明示的に要求すると、まったく同じ問題が発生すると思います。)MeasureOverrideOnRowValidationRulesChangedItemBindingGroup

BeginEditこれは、説明したように、ランダム オブジェクトの呼び出しを取得する方法を説明していません。私はそれを再現することはできません。ただし、選択したオブジェクトの二重呼び出しについては説明しています。最善の方法は、ソース オブジェクトが二重呼び出しを許容するようにコーディングすることです。

于 2011-01-03T14:53:04.340 に答える
3

.NET Framework4DataGridを使用しても同じ問題が発生します。

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 に答える