Если вы посмотрите на трассировку стека в отладчике при вызове BeginEdit
, вы увидите, что в первый раз его вызывает представление коллекции, а во второй раз — BindingGroup
.
Проблема, по-видимому, в том, что есть две вещи, которые оба думают, что они отвечают за состояние IEditableObject
. Когда WPF предоставляет представление коллекции по умолчанию, он будет искать IEditableObject
в объектах коллекции и вызывать BeginEdit
и либо EndEdit
, либо CancelEdit
в ответ на вызовы соответствующих IEditableCollectionView
методов. Но также BindingGroup
будет вызывать методы IEditableObject
в ответ на вызовы BeginEdit
и CommitEdit
или CancelEdit
.
DataGrid
использует обе функции: когда вы начинаете и завершаете редактирование подряд, он уведомляет IEditableCollectionView
и BindingGroup
, и обе эти вещи считают, что это их обязанность, в свою очередь, продолжать и уведомлять реализацию IEditableObject
на базовом исходном объекте.
Таким образом, это похоже на ошибку в DataGrid
— она заставляет два разных объекта вызывать BeginEdit
(и связанные методы). И это потому, что он использует редактируемые представления коллекции и группы привязки - судя по всему, они не были предназначены для одновременного использования на одних и тех же объектах, как их использует DataGrid
.
Причина, по которой вы не видите этой проблемы с сеткой в Toolkit, заключается в том, что она выглядит немного более старой версией — сравнивая код в ней с тем, что показывает Reflector для .NET 4.0, вы увидите, что .NET 4.0 DataGrid
имеет некоторый дополнительный код (новый метод, EnsureItemBindingGroup
, и некоторый связанный код в MeasureOverride
и OnRowValidationRulesChanged
), который гарантирует, что группа привязки всегда существует, запрашиваете вы это или нет. Поэтому, если WPF Toolkit будет обновлен, он, вероятно, расширит аналогичную функцию, если это не будет исправлено. (И я предполагаю, что если вы используете текущую версию (февраль 2010 г., когда я пишу это) набора инструментов WPF и используете свойство ItemBindingGroup
для явного запроса группы привязки, вы увидите точно такую же проблему.)
Это не объясняет, как вы получаете вызовы BeginEdit
для случайных объектов, как вы описали. Я не могу воспроизвести это. Но это объясняет двойные обращения к выбранному объекту. Кажется, лучше всего закодировать ваши исходные объекты так, чтобы они допускали двойные вызовы.
person
Ian Griffiths
schedule
03.01.2011