Verwalten mehrerer Auswahlen mit MVVM
-
03-07-2019 - |
Frage
Auf meiner Reise zum Lernen MVVM habe ich ein grundlegendes Verständnis von WPF etabliert und dem Viewmodel-Muster. Ich verwende die folgende Abstraktion, wenn eine Liste bereitstellt und bin an einem einzigen ausgewählten Elemente.
public ObservableCollection<OrderViewModel> Orders { get; private set; }
public ICollectionView OrdersView
{
get
{
if( _ordersView == null )
_ordersView = CollectionViewSource.GetDefaultView( Orders );
return _ordersView;
}
}
private ICollectionView _ordersView;
public OrderViewModel CurrentOrder
{
get { return OrdersView.CurrentItem as OrderViewModel; }
set { OrdersView.MoveCurrentTo( value ); }
}
I kann dann bindet die OrdersView zusammen mit Stütz Sortieren und Filtern, um eine Liste in WPF:
<ListView ItemsSource="{Binding Path=OrdersView}"
IsSynchronizedWithCurrentItem="True">
Das funktioniert wirklich gut für einzelne Auswahl Blick. Aber ich mag auch eine Mehrfachauswahl in der Ansicht unterstützen und das Modell bindet in der Liste der ausgewählten Elemente.
Wie würde ich die ListView.SelectedItems auf eine backer Eigenschaft auf dem Ansichtsmodell binden?
Lösung
Fügen Sie eine IsSelected
Eigenschaft, um Ihr Kind Ansichtsmodell (OrderViewModel
in Ihrem Fall):
public bool IsSelected { get; set; }
Binden Sie das ausgewählte Objekt auf den Behälter zu diesem (für ListBox in diesem Fall):
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
</Style>
</ListBox.ItemContainerStyle>
IsSelected
aktualisiert auf dem Behälter in das entsprechende Feld entsprechen.
Sie können die ausgewählten Kinder in dem View-Modell erhalten, indem Sie folgendermaßen vorgehen:
public IEnumerable<OrderViewModel> SelectedOrders
{
get { return Orders.Where(o => o.IsSelected); }
}
Andere Tipps
Ich kann Ihnen versichern: SelectedItems
ist in der Tat bindable als XAML CommandParameter
Es gibt eine einfache Lösung für dieses weit verbreitete Problem; , damit es funktioniert, müssen Sie alle die folgenden Regeln beachten:
-
Im Anschluss an Ed Balls Vorschlag , auf dem XAML-Befehl Datenbindung, definiert das
CommandParameter
Attribut Vor das AttributCommand
. Dies ist ein sehr zeitraubenden Fehler . -
Stellen Sie sicher, dass Ihr
ICommand
dieCanExecute
undExecute
Methoden einen Parameter vom Typobject
haben. Auf diese Weise können Sie verhindern zum Schweigen gebracht Besetzung Ausnahmen, die auftreten, wenn dieCommandParameter
Art der Datenbindung nicht IhreCommand
Methode der Parametertyp überein:private bool OnDeleteSelectedItemsCanExecute(object SelectedItems) { // Your code goes here } private bool OnDeleteSelectedItemsExecute(object SelectedItems) { // Your code goes here }
Zum Beispiel können Sie entweder ein ListView
/ ListBox
der SelectedItems
Eigenschaft auf Ihre ICommand
Methoden oder der ListView
/ ListBox
selbst senden. Toll, nicht wahr?
Ich hoffe, das jemanden verhindert, dass die riesige Menge an Zeit von den Ausgaben ich tat, um herauszufinden, wie SelectedItems
als CanExecute
Parameter zu erhalten.
Man kann versuchen, eine angefügte Eigenschaft zu schaffen.
Dadurch wird ein so speichern aus der Addition der IsSelected
Eigenschaft für jede einzelne Liste, die Sie binden. Ich habe es für ListBox
getan, aber es kann für einen in einer Listenansicht geändert werden.
<ListBox SelectionMode="Multiple"
local:ListBoxMultipleSelection.SelectedItems="{Binding SelectedItems}" >
Weitere Informationen: WPF - Bindung ListBox SelectedItems -. Befestigt Property VS Stil
Wenn Sie MVVM-LIGHT verwenden können Sie dieses Muster verwenden:
Nicht besonders elegant, aber sieht aus wie es zumindest zuverlässig sein sollte