2013-06-25 9 views
5

ich eine ListBox, die ich dynamisch bevölkern über eine Bindung (diese in einem DataTemplate definiert ist, weshalb die Bindung etwas ungewöhnlich ist):Listbox „IsSelected“ Bindung nur arbeiten teilweise

<ListBox SelectionMode="Extended" ItemsSource="{Binding DataContext.ResultList, RelativeSource={RelativeSource AncestorType=Window}}"> 
    <ListBox.ItemContainerStyle> 
    <Style TargetType="{x:Type ListBoxItem}"> 
     <Setter Property="IsSelected" Value="{Binding IsSelected}"/> 
    </Style> 
    </ListBox.ItemContainerStyle> 
    <ListBox.ItemTemplate> 
    <DataTemplate> 
     <Label Content="{Binding Object}"/> 
    </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

Jeder ListBoxItem ' s IsSelected Die Eigenschaft ist an eine IsSelected -Eigenschaft an einem benutzerdefinierten Objekt gebunden.

Wenn ich einzelne ListBoxItem s auswähle, funktioniert die Bindung ordnungsgemäß - die Eigenschaft IsSelected des benutzerdefinierten Objekts wird in meinem ViewModel aktualisiert. Wenn ich jedoch alle ListBoxItem s mit einem STRG + A-Befehl auswähle, werden nur die derzeit sichtbaren ListBoxItem s (die sich derzeit in meinem Bildlauffenster befinden) ihre ViewModel-Bindungen aktualisiert. Auf dem Frontend werden alle ListBoxItem s ausgewählt, und die ListBox.SelectedItems.Count -Eigenschaft auf dem Container ListBox zeigt, dass alle Elemente ausgewählt sind.

Ferner ist, wie die I ListBox blättern nachdem alle ListBoxItem s mit Strg + A der Auswahl werden die Bindungen erfolgreich aktualisiert, wenn jede ListBoxItem in Ansicht gescrollt wird.

Warum scheint diese Bindung nur teilweise zu funktionieren? Gibt es einen besseren Weg, um die Bindung der IsSelected Eigenschaft zu behandeln, wenn große Zahlen von ListBoxItems gleichzeitig ausgewählt werden können?

Edit: Dieses Verhalten tritt nicht ausschließlich mit der Strg + A-Befehl - ich die gleichen Ergebnisse erhalten, wenn alle Elemente der Auswahl eines Shift + klicken.

+1

Ich würde nicht auf die Benutzeroberfläche angewiesen, um dies zu tun, Sie würden lieber eine 'KeyBinding' und tun dies im ViewModel, oder setzen Sie etwas Code hinter und delegieren Sie die Auswahllogik auf der VM. Oder setzen Sie ein Verhalten oder etwas, das auf diese Tastenkombination reagiert. –

+0

@HighCore - Das Problem tritt nicht ausschließlich mit dem Befehl Alle auswählen auf; Das gleiche Problem tritt auf, wenn ich jedes Element mit einem Shift + Klick auswähle. –

+1

Ich stieß auf die gleiche Art von Problem. Ich gab einfach auf und verwendete eine Bindung an [SelectedItems] (http://msdn.microsoft.com/en-us/library/system.windows.controls.listbox.selecteditems.aspx) als Argument für den Click-Handler auf einem und nannte es einen Tag (Sie könnten es auch als CommandParameter für einen Befehl verwenden). Es lohnt sich nicht, die Leistung zu verringern, um die Virtualisierung zu deaktivieren, wenn die Liste lang wird. –

Antwort

5

Ich denke, das Verhalten Sie sehen zu VirtualizingStackPanel.IsVirtualizing zurückzuführen ist, die True standardmäßig ist, wenn zu ItemsSource von ListBox

verbindlich, wenn Sie zB stellen Sie Ihren ListBox wie:

<ListBox VirtualizingStackPanel.IsVirtualizing="False" SelectionMode="Extended" ItemsSource="{Binding DataContext.ResultList, RelativeSource={RelativeSource AncestorType=Window}}"> 

oder

<ListBox ...> 
    ... 
    <ListBox.ItemsPanel> 
    <ItemsPanelTemplate> 
     <StackPanel /> 
    </ItemsPanelTemplate> 
    </ListBox.ItemsPanel> 
</ListBox> 

dann sollten Sie sehen, alle Ihre gebundenen Artikel haben ihre IsSelected entsprechend mit Strg + A aktualisiert oder Umschalt + ...

Eigenschaften wie Count der Sammlung auch mit der Virtualisierung den richtigen Wert berichten würde für Dinge aufnehmen wie die erforderliche ScrollBar.Height berechnen. Elemente, die sich außerhalb des View-Ports befinden, werden nicht gerendert. Daher werden keine Bindungen wirksam, bis sie tatsächlich verwendet werden.

+0

Das hat es geschafft! Danke und toller Fang! –

+0

Es hat funktioniert. Aber was ist diese Virtualisierung und warum hat sie das Problem verursacht? –

+0

"Das Standardlayoutsystem erstellt Elementcontainer und berechnet das Layout für jedes einem Listensteuerelement zugeordnete Element. Das Wort" virtualisieren "bezieht sich auf eine Technik, bei der eine Teilmenge von UI-Elementen aus einer größeren Anzahl von Datenelementen basierend auf den Elementen generiert wird Wenn viele Elemente auf dem Bildschirm angezeigt werden, kann dies zu Leistungseinbußen führen.Das VirtualizingStackPanel berechnet die Anzahl der sichtbaren Elemente und arbeitet mit dem ItemContainerGenerator aus einem ItemsControl (z. B. ListBox oder ListView) zusammen, um UI zu erstellen Elemente nur für sichtbare Elemente. " –

Verwandte Themen