Ich habe in meinem AllCustomerView eine ListView, die mir die verfügbaren Customer anzeigt. Auf die ListView habe ich ein ContextMenu gelegt, sodass man über dieses verschiedene Methoden der Customer ausführen kann.
<UserControl.Resources>
<Style x:Key="CustomerItemStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />
</Style>
</UserControl.Resources>
<ListView
ItemContainerStyle="{StaticResource CustomerItemStyle}"
ItemsSource="{Binding AllCustomers}"
>
<ListView.ContextMenu>
<ContextMenu>
<MenuItem
Header="Register"
Command="{Binding RegisterCommand}"
/>
<!-- etc -->
Im AllCustomerViewModel rufe ich dann folgende Funktion auf. Es sollen die markieren Einträge über das ContextMenu registriert werden.
private void Register()
{
foreach (CustomerViewModel customerViewModel in AllCustomers.Where(customerViewModel => customerViewModel.IsSelected))
ThreadPool.QueueUserWorkItem(delegate { customerViewModel.Register(); });
}
Hat jemand eine Erklärung, wieso ich über STRG + A nicht dafür sorgen kann, dass alle Customer registriert werden? Es werden nur ein paar registriert, wahrscheinlich nur die, die für den Nutzer sichtbar sind. Wenn ich aber den ersten Customer markiere und dann mittels Shift + Bild unten alle markiere, werden alle registriert 😕
edit: Okay, irgendwas stimmt nicht mit der Bindung von IsSelected. Wie bindet man denn IsSelected richtig ans ViewModel? Wenn ich 3 Elemente markiert habe und diese nicht mehr im aktuellen Ausschnitt sichtbar sind, dann möchte ich diese immer deselektieren, wenn ich mit der linken Maustaste auf ein anderes einzelnes Element klicke. Das ist nämlich im Moment nicht der Fall.
Okay, irgendwas stimmt nicht mit der Bindung von IsSelected. Keine Ahnung. Ich hab grad son Listview genau in dem Stil gebaut, und das arbeitet zuverlässig.
Allerdings deine Anforderung "Items ausserhalb des sichtbaren Bereichs bei MausLinksklick deselectieren" scheint mir schwierig, und ich denke, da hast du iwelche Bugs drinne.
Normal-Verhalten ist ja, dass bei LinksKlick alle Items deselektiert (bis auf das geklickste) werden, egal ob sichtbar oder nicht.
Der frühe Apfel fängt den Wurm.
Probiere mal folgendes:
Lege eine ListView mit mehreren Elementen an, sodass du scrollen musst um die anderen Elemente zu sehen. Nun markierst du ein Element, scrollst dieses aus dem Sichtbereich und markierst dort ein Element. Du hast nun 2 Elemente markiert, das untere, welches nicht mehr sichtbar ist und das gerade Markierte. Das ist kein typisches Verhalten und hat wohl irgendwas mit Virtualization zu tun. Leider habe ich bisher noch keine sinnvolle Möglichkeit gefunden, das richtig zu stellen.
Was man machen könnte, die ganzen Tastenkombinationen im ViewModel zu Binden, aber irgendwie hab ich das Gefühl, dass man damit nicht 100% die Funktionalität wie in jedem x-beliebigen Explorer hinbiegt.
Hallo BlackMatrix,
ich kenne das Verhalten welches du beschreibst. In dem Thread How to bind IsSelected in a ListView for non-visible (virtualized) items wird auf eine Lösung im Codebehind verwiesen bei der man das SelectionChanged Event abboniert und dort dann die Selektionen manuel setzt.
Lg, XXX
Das macht natürlich Sinn und da es sich ja nur um UI-Logik handelt, gehört es da auch hin.
Ich hab nun
<UserControl.Resources>
<Style x:Key="CustomerItemStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />
</Style>
</UserControl.Resources>
vollständig entfernt und
<ListView
ItemsSource="{Binding AllAccounts}"
SelectionChanged="ListView_SelectionChanged"
>
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
foreach (CustomerViewModel vm in ((ListView)sender).Items)
{
if (e.AddedItems.Contains(vm))
vm.IsSelected = true;
else
vm.IsSelected = false;
}
}
hinzugefügt und es scheint zu funktionieren.
@xxxprod:
Wie hast du die Selektionen gesetzt? Ich habe teilweise immer noch komische Verhalten 😦
Hallo BlackMatrix,
ich habe das selber noch nie benötigt sondern nur ein Beispiel für dich im Netz gegoogelt. Was für ein komisches Verhalten bemerkst du denn? Mir fällt bei deinem Codeschnippsel nur auf, dass du immer alle Items durchiterierst und IsSelected setzt. Vielleicht ändert sich ja das Verhalten schon, wenn du nur die "AddedItems" und "RemovedItems" aus der SelectionChangedEventArgs-Klasse behandelst.
Lg, XXX
Stimmt, das wäre natürlich von der Logik her sinnvoller, nur die Elemente anzupacken bei denen auch wirklich die Selektierung geändert wurde.
Naja, das Problem war das immer noch Elemente markiert waren, die es eigentlich nicht sein sollten.
Ich hatte den Code dahingehend abgeändert:
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
foreach (CustomerViewModel vm in ((ListView)sender).Items)
{
if (e.AddedItems.Contains(vm))
vm.IsSelected = true;
else if(e.RemovedItems.Contains(vm)
vm.IsSelected = false;
}
}
Des Weiteren hatte ich ein Problem bei der Filterung und dem IsSelected. Ich habe eine bestimmte Menge im ListViewControl markiert, dann habe ich über eine Textbox die Elemente gefiltert und anschließend erstmal alle Selektionen im ViewModel entfernt. Somit muss der Benutzer erneut markieren.
Was mich daran gestört hat. Ich muss in der View und im ViewModel daran denken, dass immer richtig selektiert ist.
Die Frage ist, wie ist eigentlich die intuitive bzw. die von Windows standardisierte Vorgehensweise? Wird bei einer Filterung automatisch jegliche Selektion entfernt, sind nur noch die Elemente markiert, die durch den Filter durchkommen und/oder muss ich die Markierung von den Elementen wieder herstellen, sobald der Filter wieder herausgenommen wird?
Bzgl. der Items die trotzdem selektiert bleiben fällt mir leider gerade nichts mehr dazu ein.
Bzgl. der Vorgehensweise glaub ich, dass das Geschmackssache ist: Ich hab zum Beispiel mal eine Filterfunktion umgesetzt, die sich nur die sichtbaren Items merkt. Wenn der Filter wieder aufgelöst wird, sind nur die zuletzt markierten Elemente wieder markiert.
Falls das mit den virtuellen Items und dem IsSelected nicht hinhauen mag, bleibt dir denke ich nicht mehr viele Optionen.
Eine wäre, die nicht-funktionierende Logik selber nachzufrickeln. Zb. Bei einem ItemSelected auch noch prüfen ob die Shift Taste gedrückt war usw. Aber das ist nicht wirklich eine schöne Lösung. Oder du findest ein anderes Control das damit besser zurecht kommt.
Lg, XXX