Domanda

Nel mio viaggio verso l'apprendimento di MVVM ho stabilito alcune conoscenze di base su WPF e sul modello ViewModel. Sto usando la seguente astrazione quando fornisco un elenco e sono interessato a un singolo elemento selezionato.

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

Posso quindi associare il OrdersView insieme a supportare l'ordinamento e il filtro a un elenco in WPF:

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

Funziona davvero bene per le viste a selezione singola. Ma vorrei supportare anche selezioni multiple nella vista e fare in modo che il modello si legasse all'elenco degli elementi selezionati.

Come assocerei ListView.SelectedItems a una proprietà backer su ViewModel?

È stato utile?

Soluzione

Aggiungi una proprietà IsSelected a ViewModel di tuo figlio ( OrderViewModel nel tuo caso):

public bool IsSelected { get; set; }

Associa la proprietà selezionata sul contenitore a questa (per ListBox in questo caso):

<ListBox.ItemContainerStyle>
    <Style TargetType="{x:Type ListBoxItem}">
        <Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
    </Style>
</ListBox.ItemContainerStyle>

IsSelected viene aggiornato per corrispondere al campo corrispondente sul contenitore.

È possibile ottenere i bambini selezionati nel modello di visualizzazione procedendo come segue:

public IEnumerable<OrderViewModel> SelectedOrders
{
    get { return Orders.Where(o => o.IsSelected); }
}

Altri suggerimenti

Posso assicurarti che SelectedItems è effettivamente associabile come XAML CommandParameter

Esiste una soluzione semplice a questo problema comune; per farlo funzionare devi seguire TUTTI le seguenti regole:

  1. Seguendo il suggerimento di Ed Ball , nel database dei comandi XAML, definire il CommandParameter attributo PRIMA dell'attributo Command . Questo è un bug che richiede molto tempo .

    inserisci qui la descrizione dell

  2. Assicurati che i metodi ICommand CanExecute e Execute abbiano un parametro di tipo oggetto . In questo modo è possibile impedire le eccezioni silenziate che si verificano ogni volta che il tipo CommandParameter della banca dati non corrisponde al tipo di parametro del metodo Command :

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

Ad esempio, puoi inviare una proprietà ListView / ListBox SelectedItems ai tuoi metodi ICommand o ListView / ListBox stesso. Fantastico, vero?

Spero che questo impedisca a qualcuno di spendere l'enorme quantità di tempo che ho fatto per capire come ricevere SelectedItems come parametro CanExecute .

Si può provare a creare una proprietà collegata.

In questo modo si salverà uno dall'aggiunta della proprietà IsSelected per ogni elenco associato. L'ho fatto per ListBox , ma può essere modificato per l'uso in una vista elenco.

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

Ulteriori informazioni: WPF - ListBox SelectedItems - Proprietà associata VS Style .

Se stai usando MVVM-LIGHT puoi usare questo schema:

https: // galasoft .ch / posts / 2010/05 / movimentazione-datagrid-SelectedItems-in-un'amichevole-maniera-MVVM-

Non particolarmente elegante ma sembra che dovrebbe essere affidabile almeno

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top