2015-04-17 117 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

相關問題