Mam ListBox
że ma swoje ItemsSource
związany z klasy niestandardowej, która (prawidłowo) implementuje INotifyCollectionChanged
i SelectedItem
związany z polem w ViewModel.wybór Usuń gdy wybrana pozycja zostanie usunięta z pola listy
Problem polega na tym, że po usunięciu aktualnie SelectedItem
z kolekcji ItemsSource
natychmiast zmienia ona wybór na sąsiedni element. Bardzo bym wolał, gdyby po prostu usunięto selekcję.
Powodem, dla którego jest to dla mnie problemem jest podążanie. Klasa ItemsSource
zawiera elementy z innej kolekcji, które albo spełniają pewne predykaty (podczas stałej czasu wykonywania), albo są Active
. Bycie Active
jest "zsynchronizowane" z byciem SelectedItem
(istnieją ku temu powody). Jest więc bardzo możliwe, że dany przedmiot może być dozwolony tylko w przypadku, gdy jest wybrany, co oznacza, że może on zniknąć, gdy użytkownik wybierze inny element.
Moja funkcja (głęboko w „modelu”), która jest wywoływana gdy SelectedItem
ulega zmianie:
//Gets old Active item
var oldActiveSchema = Schemas.FirstOrDefault(sch => sch.IsActive);
//Makes the new Item active (which triggers adding it into `ItemsSource` in case it didn't satisfy the Predicate)
((PowerSchema)newActiveSchema).IsActive = true;
//Triggers PropertyChanged on ViewModel with the new Active item
CurrentSchema = newActiveSchema;
RaisePropertyChangedEvent(nameof(CurrentSchema)); (#1)
//Changes the old item so it stops being Active -> gets removed from `ItemsSource` (#2)
if (oldActiveSchema != null) { ((PowerSchema)oldActiveSchema).IsActive = false; }
Problem jest, że z jakiegoś powodu aktualizację ListBox
ze względu na zmianę SelectedItem
który powinien uzyskać wyzwolone przez (# 1) zostaje odroczone (wiadomość o aktualizacji ListBox
prawdopodobnie kończy się pętlą wiadomości WPF i czeka tam do chwili zakończenia obecnego obliczania).
Usunięcie oldActiveSchema
z ItemsSource
, z drugiej strony, jest natychmiastowe, a także natychmiast wyzwala zmianę SelectedItem
do jednego, który jest obok starego (jeśli usunąć wybraną pozycję, sąsiedni zostanie wybrany zamiast) . A ponieważ zmiana SelectedItem
uruchamia moją funkcję, która ustawia CurrentSchema
na niewłaściwy (sąsiedni) element, przepisuje on wybrany przez użytkownika CurrentSchema
(nr 1) i do czasu, kiedy wiadomość o aktualizacji ListBox
spowodowana PropertyChanged
zostanie uruchomiona, po prostu zaktualizuje ją do sąsiedni.
Każda pomoc jest bardzo doceniana.
rzeczywisty kod, jeśli ktoś chciałby kopać głębiej:
- ListBox
- ViewModel
- The model's method
- Callstack kiedy sąsiedni element zostanie wybrany jako
SelectedItem
zamiast jednego użytkownika wybrał- przewód 46: the
SelectedItem
wybrany przez użytkownika wkracza w sposób jako taki, który ma się uzyskać aktywny - linia 45: stare
SelectedItem
przestanie być aktywny -> usuwany jest ze zbioru (44-41) - linia 32:
MoveCurrencyOffDeletedElement
poruszaSelectedItem
- linia 5:
SelectedItem
zostaje zmieniona na sąsiedni jeden
- przewód 46: the
Usuwanie zaznaczenia powinno po prostu wymagać ustawienia właściwości SelectedItem w twoim ViewModel na wartość null.Ponieważ problem polega na zmianie schematu, wystarczy zapisać wybranyitem w zmiennej lokalnej, ustawić selecteditem na wartość null, a * następnie * usunąć wybrany element z kolekcji. –
Wpadnij [#WPF] (https://chat.stackoverflow.com/rooms/18165/wpf) i zostaw mi ping, jeśli nie jestem aktywny na czacie. Spojrzałem na twój kod, ale nie mogę od razu dowiedzieć się, jak wywołać ten problem. Jest też sporo innych pomocnych mieszkańców, którzy mogą pomóc, jeśli jestem nieaktywny. – Maverik
I rzeczywiście pomysł Brandona na zmianę wyboru jest tym, o czym myślałem. Także jeśli bindujesz Selector.IsSelected na IsActive ... Twój wybór może automatycznie podążać za flagą IsActive, nie mając do czynienia z bieżącym przedmiotem – Maverik