2015-04-17 111 views
1

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

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中类似的东西?

+0

将此事件方法设置为属性,该属性可以自我提升并使用其他属性与列表视图进行绑定。 – JSJ

+0

我对MVVM真的很陌生,所以我会用一些进一步的描述来欣赏一些exmaple – MajkeloDev

回答

2

我建议一个解决方案,如下面的伪代码。绑定的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兴趣也。它会增强你的数据绑定。

+0

我只是想出了类似的somtehing,所以我想我想的很好。我会试试这个。 – MajkeloDev

1

如果我理解正确,你想要的是在ViewModel中处理SelectionChanged,并对itemsForListView1itemsForListView2进行一些更改,而不是你在View中目前正在做什么?

1)在视图模型,你需要:创建一个ICommand公共财产,它可以从Microsoft.Practices.Composite.Presentation.Commands被实例化,例如为DelegateCommand

... 
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)鉴于需要绑定加载和的SelectionChanged到新在视图模型创建的命令,并希望您的ListView控件绑定到该集合在视图模型

<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。

+0

accpeted的答案完全一样,但以更简单的方式,这就是我接受它的原因。无论如何感谢您的答案。 – MajkeloDev

相关问题