ComboBox SelectionChanged 在 MVVM 中

ComboBox SelectionChanged in MVVM

我在 WPF 中有一个没有 MVVM 的应用程序,我决定将其重构为 MVVM。我遇到了 ComboBox SelectionChanged 事件的问题。基本上为了使它更简单让我们假设我有一个 ComboBox 和 2 个 ListView。每个 ComboBoxItem 都是一个集合。第一个 ListView 的 ItemsSource 绑定到 ComboBox.SelectedValue 中的集合,但仅绑定到 属性(十进制)大于零的部分。第二个 ListView 的 ItemsSource 绑定到同一个集合,但绑定到第二部分(一些大于零的道具)。下面一些代码来理解

private void myCombo_selectionChanged(object sender, SelectionChangedEventArgs e)
{
    ComboBox myCmb = sender as ComboBox;
    List<myType> myList = myCmb.SelectedValue as List<myType>;

    itemsForListView1 = myList.Where((x) => x.myProp > 0); 
    itemsForListView2 = myList.Where((x) => x.myProp < 0);
    // Above 2 collections are of Type List<myType> and their scope will be whole ViewModel, 
    //so i assume i just need to change them and RaisePropChanged but how to change them without breaking mvvm ?

    MyListView1.ItemsSource = itemsForListView1;
    MyListView2.ItemsSource = itemsForListView2;
}

我怎样才能在 MVVM 中实现类似的东西?

我建议使用下面伪代码中的解决方案。将 SelectedItem 与您的 myCombo 的 SelectedValue 绑定,并将 ItemsListViewX 与您的 ListView

绑定
private List<T> selectedItem;
public List<T> SelectedItem
{
    get { return selectedItem; }
    set
    {
        if (value != selectedItem)
        {
            selectedItem = value;

            ItemsListView1 = new ObservableCollection<T>(selectedItem.Where(x=>x.Prop>0));
            ItemsListView2 = new ObservableCollection<T>(selectedItem.Where(x=>x.Prop<0));
            NotifyOfPropertyChange(() => SelectedItem);         
        }
    }
}

private ObservableCollection<T> itemsListView1;
public ObservableCollection<T> ItemsListView1
{
    get { return itemsListView1; }
    set
    {
        if (value != itemsListView1)
        {
            itemsListView1 = value;
            NotifyOfPropertyChange(() => ItemsListView1);
        }
    }
}

private ObservableCollection<T> itemsListView2;
public ObservableCollection<T> ItemsListView2
{
    get { return itemsListView2; }
    set
    {
        if (value != itemsListView2)
        {
            itemsListView2 = value;
            NotifyOfPropertyChange(() => ItemsListView2);
        }
    }
}

也许您也对 MVVM Framework 感兴趣。它将增强您的数据绑定。

如果我理解正确,你想要的是处理 ViewModel 中的 SelectionChanged 并对 itemsForListView1itemsForListView2 进行一些更改,而不是你在视图中所做的时刻?

1) 在 ViewModel 中,您需要:创建一个 ICommand public 属性,它可以实例化为 DelegateCommand 来自 Microsoft.Practices.Composite.Presentation.Commands

...
public ViewModelConstructor(...)
{
    ...
    SelectionChangedCommand = new DelegateCommand<List<myType>>(SelectionChangedExecute);
    ...
}
...
public List<myType> ItemsForListView1 {get; private set} // Implement INotifyPropertyChanged here
public List<myType> ItemsForListView1 {get; private set} // Implement INotifyPropertyChanged here
...
public ICommand SelectionChangedCommand { get; private set; }

private void SelectionChangedExecute(List<myType> parameter)
{
    ItemsForListView1 = parameter.Where((x) => x.myProp > 0).ToList(); 
    ItemsForListView2 = parameter.Where((x) => x.myProp < 0).ToList();
}
...

2) 在 View 中,您希望将 Loaded 和 SelectionChanged 绑定到 viewmodel 中新创建的命令,并且您希望 ListView 绑定到 ViewModel

中的集合
<ComboBox x:Name="MyComboBox" SelectedIndex="0" ItemsSource="{Binding YourCollectionWithDifferentLists}">
<i:Interaction.Triggers>
    <i:EventTrigger EventName="Loaded">
        <i:InvokeCommandAction Command="{Binding SelectionChangedCommand}" CommandParameter="{Binding ElementName=Combo, Path=SelectedItem}"></i:InvokeCommandAction>
    </i:EventTrigger>
    <i:EventTrigger EventName="SelectionChanged">
        <i:InvokeCommandAction Command="{Binding SelectionChangedCommand}" CommandParameter="{Binding ElementName=Combo, Path=SelectedItem}"></i:InvokeCommandAction>
    </i:EventTrigger>
</i:Interaction.Triggers>

如果您的集合正在更改并且您希望在 UI 上显示更改,您可能希望使用 ObservableCollection 而不是 List。如果要在选择更改事件后创建新集合,则需要以任何一种方式实现 INotifyPropertyChanged。