Pregunta

En mi viaje hacia el aprendizaje de MVVM, he establecido cierta comprensión básica de WPF y el patrón de 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 ); } 
}

Luego puedo enlazar el OrdersView junto con la clasificación y el filtro compatibles a una lista en WPF:

<ListView ItemsSource="{Binding Path=OrdersView}" 
          IsSynchronizedWithCurrentItem="True">

Esto funciona realmente bien para vistas de selección individuales. 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 enlazaría ListView.SelectedItems a una propiedad de respaldo en ViewModel?

¿Fue útil?

Solución

Agregue una propiedad IsSelected a su hijo ViewModel ( OrderViewModel en su caso):

public bool IsSelected { get; set; }

Enlazar 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); }
}

Otros consejos

Le puedo asegurar: SelectedItems es de hecho vinculable como un CommandParameter XAML

Hay una solución simple para este problema común; para que funcione, debe seguir TODOS las siguientes reglas:

  1. Siguiendo la sugerencia de Ed Ball , en el enlace de datos del comando XAML, defina el CommandParameter atributo ANTES del atributo Comando . Este es un error que consume mucho tiempo .

    ingrese la descripci&oacute;n de la imagen aqu&iacute;

  2. Asegúrese de que los métodos de ICommand de CanExecute y Execute tengan un parámetro de tipo objeto . De esta manera, puede evitar que las excepciones de conversión silenciadas se produzcan cuando el tipo de parámetro CommandParameter del enlace de datos no coincida con el tipo de parámetro del método Command :

    private bool OnDeleteSelectedItemsCanExecute(object SelectedItems)  
    {
         // Your code goes here
    }
    
    private bool OnDeleteSelectedItemsExecute(object SelectedItems)  
    {
        // Your code goes here
    }
    

Por ejemplo, puede enviar la propiedad ListView / ListBox de SelectedItems a sus métodos de ICommand o el ListView / ListBox en sí mismo. Genial, ¿no?

Espero que esto evite que alguien pase la gran cantidad de tiempo que hice para averiguar cómo recibir SelectedItems como un parámetro CanExecute .

Uno puede intentar crear una propiedad adjunta.

Al hacerlo, se guardará uno al agregar la propiedad IsSelected para cada una de las listas que enlaza. Lo he hecho para ListBox , pero se puede modificar para usarlo en una vista de lista.

<ListBox SelectionMode="Multiple"
         local:ListBoxMultipleSelection.SelectedItems="{Binding SelectedItems}" >

Más información: WPF - Binding ListBox SelectedItems - Property Attached VS Style .

Si está utilizando MVVM-LIGHT, puede usar este patrón:

https: // galasoft .ch / posts / 2010/05 / handling-datagrid-selecteditems-in-an-mvvm-friendly-manner

No es especialmente elegante, pero parece que debería ser confiable al menos

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top