Jeśli spojrzeć na ślad stosu w debugger gdy BeginEdit
nazywa, będziesz Zobacz, że za pierwszym razem jest to widok kolekcji nazywający go, a po raz drugi to BindingGroup
.
Problem polega na tym, że istnieją dwie rzeczy, które według obu są odpowiedzialne za stan IEditableObject
. Gdy WPF udostępnia domyślny widok kolekcji, będzie szukał IEditableObject
obiektów w kolekcji i wywoła BeginEdit
i EndEdit
lub CancelEdit
w odpowiedzi na wywołania do odpowiednich metod IEditableCollectionView
. Ale również, BindingGroup
wywoła metody IEditableObject
w odpowiedzi na wywołania BeginEdit
i CommitEdit
lub CancelEdit
.
DataGrid
wykorzystuje obie funkcje: po uruchomieniu i kompletne edycje z rzędu, to powiadamia IEditableCollectionView
i się BindingGroup
i obie z tych rzeczy, myślę, że to jest ich odpowiedzialność z kolei, aby przejść dalej i powiadomić realizację IEditableObject
na podstawowy obiekt źródłowy.
Wygląda więc jak błąd w DataGrid
- powoduje, że dwa różne obiekty wywołują BeginEdit
(i powiązane metody). A to dlatego, że korzysta z edytowalnych widoków kolekcji i grup powiązań - na pierwszy rzut oka te nie zostały zaprojektowane do użycia w tym samym czasie na tych samych obiektach, w sposób, w jaki używa ich DataGrid
.
Powodem, dla którego nie widzisz tego problemu z siatką w Toolkit jest to, że wygląda na nieco starszą wersję - porównując kod z tym, co Reflector pokazuje dla .NET 4.0, zobaczysz, że .NET 4.0 DataGrid
ma dodatkowy kod (nową metodę, EnsureItemBindingGroup
i pewien powiązany kod w MeasureOverride
i OnRowValidationRulesChanged
), który zapewnia, że grupa wiążąca zawsze istnieje, niezależnie od tego, czy o to prosisz, czy nie. Jeśli więc zestaw narzędzi WPF zostanie zaktualizowany, prawdopodobnie będzie miał podobną funkcję, chyba że zostanie naprawiony.(Przypuszczam, że jeśli użyjesz bieżącej wersji - w lutym 2010 r., Kiedy to piszę - zestawu narzędzi WPF i użyjesz właściwości ItemBindingGroup
, aby poprosić o jawnie grupę wiążącą, zobaczysz dokładnie ten sam problem.)
To nie wyjaśnia, w jaki sposób można uzyskać połączenia z obiektami losowymi, zgodnie z opisem. Nie mogę tego zaszkodzić. Ale wyjaśnia podwójne połączenia na wybranym obiekcie. Najlepszym rozwiązaniem wydaje się kodowanie obiektów źródłowych, aby tolerowały podwójne połączenia.
Brzmiało interesująco, więc sprawdziłem swoje DataGrid, które jest również powiązane z ObservableCollection i nie doświadczyłem tego ...? Moja reprezentacja to jeden obiekt w wierszu, czy przypadkiem łączysz obiekty, które implementują IEditableObject lub coś podobnego? –
Interesujące. Mój obiekt implementuje tylko IEditableObject i INotifyPropertyChanged, więc nie ma łączenia. Moja ObservableCollection jest jednak opakowana w niestandardowy ListCollectionView. I włączyłem kolumnę do właściwości klasy w moim obiekcie IEditableObject, a nie bezpośrednio do właściwości obiektu IEditableObject. Przynajmniej teraz mam powód, by sprawdzić moje źródło, dzięki! – Sam
Przykłady MSDN zawsze zawierają flagę, która uniemożliwia BeginEdit wykonywanie swoich zadań, gdy jest wywoływana w dowolnym momencie, ale w pierwszej kolejności. Z mojego doświadczenia wynika, że tak, to się nazywa wiele razy. – peterG