Ответ 1
Если вы посмотрите на трассировку стека в отладчике при вызове 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
на случайных объектах, как вы описали. Я не могу воспроизвести это. Но он объясняет двойные вызовы на выбранном объекте. Лучше всего сделать код, чтобы закодировать исходные объекты, чтобы они терпели двойные вызовы.