Подтвердить что ты не робот

Управление несколькими выборами с помощью MVVM

В моем путешествии по изучению MVVM я установил базовое понимание WPF и шаблона ViewModel. Я использую следующую абстракцию при предоставлении списка и интересуюсь одним выбранным элементом.

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

Затем я могу связать OrdersView с поддержкой сортировки и фильтрации в списке в WPF:

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

Это очень хорошо работает для одиночного выбора. Но я хотел бы также поддерживать несколько вариантов в представлении и привязать модель к списку выбранных элементов.

Как мне привязать ListView.SelectedItems к свойству backer в ViewModel?

4b9b3361

Ответ 1

Добавьте свойство IsSelected вашему ребенку ViewModel (OrderViewModel в вашем случае):

public bool IsSelected { get; set; }

Привяжите выбранное свойство к контейнеру к этому (для этого в ListBox):

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

IsSelected обновляется, чтобы соответствовать соответствующему полю контейнера.

Вы можете получить выбранные дочерние элементы в модели представления, выполнив следующие действия:

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

Ответ 2

Я могу заверить вас: SelectedItems действительно может быть связан как XAML CommandParameter

Существует простое решение этой общей проблемы; чтобы он работал, вы должны следовать ВСЕ следующим правилам:

  • Следуя рекомендациям Ed Ball, в вашей привязке к команде XAML, укажите атрибут CommandParameter ПЕРЕД атрибут Command, Это очень трудоемкая ошибка.

    enter image description here

  • Убедитесь, что у ваших методов ICommand CanExecute и Execute есть параметр типа object. Таким образом, вы можете запретить исключенные исключения исключения, возникающие всякий раз, когда тип привязки CommandParameter не соответствует вашему типу параметра метода Command:

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

Например, вы можете отправить свойство ListView/ListBox SelectedItems в свои методы ICommand или ListView/ListBox. Отлично, не так ли?

Надеюсь, это мешает кому-то потратить огромное количество времени, которое я сделал, чтобы выяснить, как получить SelectedItems как параметр CanExecute.

Ответ 3

Можно попытаться создать прикрепленное свойство.

Это позволит сохранить одно из добавления свойства IsSelected для каждого связанного списка. Я сделал это для ListBox, но его можно изменить для использования в виде списка.

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

Дополнительная информация: WPF - привязка ListBox SelectedItems - привязанный свойство VS Style.