c# - ejemplo - xamarin bindingcontext
Administrar selecciones múltiples con MVVM (4)
Agregue una propiedad IsSelected a su hijo ViewModel ( OrderViewModel en su caso):
public bool IsSelected { get; set; }
Enlace la propiedad seleccionada en el contenedor a esto (para ListBox en este caso):
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
</Style>
</ListBox.ItemContainerStyle>
IsSelected se actualiza para que coincida con el campo correspondiente en el contenedor.
Puede obtener los elementos secundarios seleccionados en el modelo de vista haciendo lo siguiente:
public IEnumerable<OrderViewModel> SelectedOrders
{
get { return Orders.Where(o => o.IsSelected); }
}
En mi viaje hacia el aprendizaje de MVVM, he establecido una comprensión básica de WPF y el patrón ViewModel. Estoy utilizando la siguiente abstracción al proporcionar una lista y estoy interesado en un solo elemento seleccionado.
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 ); }
}
A continuación, puedo vincular el OrdersView junto con la ordenación y filtrado de apoyo a una lista en WPF:
<ListView ItemsSource="{Binding Path=OrdersView}"
IsSynchronizedWithCurrentItem="True">
Esto funciona muy bien para vistas de selección única. Pero también me gustaría admitir selecciones múltiples en la vista y hacer que el modelo se vincule a la lista de elementos seleccionados.
¿Cómo vincularía ListView.SelectedItems a una propiedad de respaldo en ViewModel?
Puedo asegurarle que SelectedItems es enlazable como un CommandParameter XAML
Hay una solución simple para este problema común; para que funcione, debes seguir TODAS las siguientes reglas:
Siguiendo la sugerencia de Ed Ball , en su enlace de datos del comando XAML, defina el atributo
CommandParameterANTES del atributoCommand. Este es un error que consume mucho tiempo .Asegúrese de que los métodos
CanExecuteyExecutesuICommandtengan un parámetro de tipoobject. De esta forma, puede evitar las excepciones deCommandParametersilenciadas que se producen cada vez que el tipoCommandParameterlaCommandParameterde datos no coincide con el tipo de parámetro de su método deCommand:private bool OnDeleteSelectedItemsCanExecute(object SelectedItems) { // Your code goes here } private bool OnDeleteSelectedItemsExecute(object SelectedItems) { // Your code goes here }
Por ejemplo, puede enviar una propiedad SelectedItems ListView / ListBox a sus métodos ICommand o al ListView / ListBox . Genial, ¿verdad?
Espero que esto evite que alguien pase la gran cantidad de tiempo que hice para descubrir cómo recibir SelectedItems como un parámetro CanExecute .
Si está usando MVVM-LIGHT puede usar este patrón:
No es especialmente elegante, pero parece que debería ser confiable al menos
Uno puede intentar crear una propiedad adjunta.
Si lo hace, le ahorrará a uno agregar la propiedad IsSelected para todas y cada una de las listas que enlaza. Lo hice para ListBox , pero puede modificarse para usarlo en una vista de lista.
<ListBox SelectionMode="Multiple"
local:ListBoxMultipleSelection.SelectedItems="{Binding SelectedItems}" >
Más información: WPF - Vinculando ListBox SelectedItems - Propiedad adjunta VS Style .