Если вы посмотрите на трассировку стека в отладчике при вызове 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