2012-05-18 8 views
5

Mam więc tabelę klienta, zawierającą rekordy klienta, rekord, z których każdy ma niestandardowe pole typu. Mam również niestandardową tabelę, zawierającą prawidłowe wartości pola niestandardowego typu.WPF/XAML - Umożliwienie ComboBox mieć SelectedValue, które nie jest w ItemsSource

Potrzebuję WPF do zrobienia CRUD. (Twórz, przeglądaj, aktualizuj, usuwaj).

Oczywistym rozwiązaniem jest użycie składnika ComboBox z jego właściwością SelectedValue powiązaną z polem niestandardowym, a jego właściwość ItemsSource powiązana z listą wypełnioną przez zapytanie w tabeli niestandardowego typu.

Problem polega na tym, że to nie działa, z wyjątkiem prostego problemu, który widzisz w ćwiczeniach.

Trudność pojawia się podczas przeglądania lub edytowania rekordu klienta, który ma niestandardową wartość, która nie znajduje się w niestandardowej tabeli. Może się to zdarzyć przez błąd lub może się zdarzyć, ponieważ typ niestandardowy został wycofany i usunięty z tabeli.

W tym przypadku WPF ustawia wartość pola customertype na wartość null, ponieważ wartość SelectedValue nie znajduje się na liście ItemsSource. I to jest problem.

Jeśli oglądasz tylko, powinieneś zobaczyć wartość, która znajduje się w tabeli, niezależnie od tego, czy znajduje się na liście. Jeśli edytujesz, możesz uzasadnić argument, że powinieneś również pokazać wartość, która jest w tabeli, przynajmniej początkowo, ale jeśli zmienisz wybór, nie możesz uzyskać tego, co zacząłeś.

Jakieś pomysły? Jest to problem, który występuje na prawie każdym formularzu edycji/widoku, więc wolałbym coś, co jest rozsądnie czyste w punkcie użytkowania. (To znaczy, biorąc pod uwagę wybór komplikacji w XAML, w każdym miejscu muszę obsłużyć jedno z tych pól lub komplikację w kodzie, który wspiera XAML, który wstawiam, aby obsłużyć jedno z tych pól, wolałbym ten ostatni.)

Odpowiedz

3

Proponuję, aby nie wiązać swojego ItemsSource bezpośrednio do zawartości tabeli CustomerType. Zamiast tego należy połączyć pozycje ItemsSource dla elementów typu Customer w tabelach typu klienta i wszystkie wartości CustomerType przechowywane w rekordach klienta, które nie istnieją w tabeli typu klienta. Gdy użytkownik przejdzie od przeglądania do edycji, zaktualizuj kolekcję, aby używać tylko tych elementów w tabeli CustomerType. Gdy użytkownik przejdzie w tryb wyświetlania, przełącz się z powrotem do kolekcji scalonej.

+0

Próbuję tego, i to nie działa. Kod znajdujący się za ItemsSource combobox teraz wstawia bieżącego customerid, jeśli nie znajduje się w tym, co jest zwracane z bazy danych, jeśli przeglądamy istniejący rekord. Ale jeśli zmienię, aby edytować nowy rekord, podnoszę PropertyChanged na właściwości ItemsSource, aw debugerze widzę kod o nazwie, a także nowo utworzoną listę, która nie zawiera dodatkowej wartości, ale w interfejsie użytkownika, Wciąż widzę pierwszą listę. –

+0

Czy sprawdzasz za pomocą ObservableCollection dla swoich ItemsSource lub INotifyPropertyChanged, gdy zmienia się kolekcja List? – Josh

+0

Trochę zamieszania z mojej strony. Nie wychowywałem się propertychanged na nieruchomości, które myślałem, że jestem. –

0

Podczas gdy powyższa odpowiedź służy, w każdym przypadku oznacza to sporą ilość kodu. Ten problem istnieje jako ogólny wzór, każde miejsce, w którym lista pochodzi z jednego miejsca, a wybrana wartość pochodzi z innej.

Wciąż nie zdecydowałem się na rozwiązanie, ale moja ostatnia próba okazuje się obiecująca.

To, co zrobiłem, to wyprowadzić nową klasę z ComboBox. Do tego dodałem nową zależność DependencyProperty - AddSelectedIfMissing. A następnie przesłonię OnItemsChanged(). W nim sprawdzam, czy SelectedValue pasuje do pola SelectedValuePath dowolnego elementu w ItemsSource.

Wiążę ItemsSource z właściwością viewmodel, która zwraca kolekcję obiektów rekordów reprezentujących prawidłowe wybory. Wiążę SelectedValue z właściwością viewmodel, która zawiera istniejącą wartość. I wiążę AddSelectedIfMissing do właściwości boolean z viewmodel, który jest prawdziwy, gdy chcę dodać SelectedValue do ItemsSource.

Po zmianie z widoku na edycję podnosimy właściwości PropertyChanged do właściwości powiązanej z ItemsSource, więc kontrolka przeładuje ją ponownie.

Co mam teraz ma pewne ograniczenia. Zależy to od możliwości rzutowania ItemsSource z obiektu na IList, a także możliwość rzutowania każdego przedmiotu z obiektu na znaną klasę bazową, z której możemy pobrać wartości pól. I nie zadziałałoby, gdybym powiązał SelectedItem, zamiast SelectedValue.

Ale w ramach tych ograniczeń działa dobrze.

+1

Czy możesz zamieścić swój kod dla tego? Rozumiem, że to stare pytanie, ale mam podobny problem i byłbym nim zainteresowany. – PlTaylor

Powiązane problemy