IT박스

MVVM으로 다중 선택 관리

itboxs 2020. 12. 8. 07:51
반응형

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

그런 다음 WPF의 목록에 정렬 ​​및 필터링을 지원하는 것과 함께 OrdersView를 바인딩 할 수 있습니다.

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

이것은 단일 선택 뷰에서 정말 잘 작동합니다. 그러나 뷰에서 다중 선택을 지원하고 모델이 선택한 항목 목록에 바인딩되도록하고 싶습니다.

ListView.SelectedItems를 ViewModel의 후원자 속성에 어떻게 바인딩합니까?


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

장담 할 수 있습니다 : SelectedItems실제로 XAML로 바인딩 가능 합니다.CommandParameter

이 일반적인 문제에 대한 간단한 해결책이 있습니다. 작동하려면 다음 규칙을 모두 따라야합니다 .

  1. 다음 에드 볼의 제안 , 당신의 XAML 명령 데이터 바인딩에서 정의 CommandParameter속성 전에Command 속성을. 이것은 매우 시간이 많이 걸리는 버그 입니다.

    여기에 이미지 설명 입력

  2. ICommandCanExecuteExecute메소드에 유형의 매개 변수가 있는지 확인하십시오 object. 이렇게 하면 데이터 바인딩의 유형이 메서드의 매개 변수 유형 과 일치하지 않을 때마다 발생 하는 침묵 캐스트 예외를 방지 할 수 있습니다 .CommandParameterCommand

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

For example, you can either send a ListView/ListBox's SelectedItems property to your ICommand methods or the ListView/ListBox itself. Great, isn't it?

I hope this prevents someone from spending the huge amount of time I did to figure out how to receive SelectedItems as a CanExecute parameter.


One can try creating an attached property.

Doing so will save one from adding the IsSelected property for each and every list you bind. I have done it for ListBox, but it can be modified for use a in a list view.

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

More info: WPF – Binding ListBox SelectedItems – Attached Property VS Style .


If you're using MVVM-LIGHT you can use this pattern:

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

특히 우아하지는 않지만 적어도 신뢰할 수 있어야 할 것 같습니다.

참고 URL : https://stackoverflow.com/questions/803216/managing-multiple-selections-with-mvvm

반응형