2015-04-17 4 views
1

У меня есть приложение в WPF без MVVM, я решил реорганизовать это на MVVM. Я столкнулся с проблемой с событием ComboBox SelectionChanged. В основном, чтобы упростить это, предположим, что у меня есть один ComboBox и 2 ListView. Каждый ComboBoxItem является коллекцией. Первый элемент ListView ListSource привязан к коллекции из ComboBox.SelectedValue, но только к той части, чье одно свойство (десятичной) больше нуля. Второй элемент ListView ListSource привязан к одному и тому же кругу, но ко второй части (некоторая поддержка больше нуля). Ниже приведен код кодаComboBox SelectionChanged в MVVM

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, поэтому я буду оценивать некоторые примеры с последующим описанием – MajkeloDev

ответ

2

Предлагаю решение, как в псевдокоде ниже. Bind SelectedItem с SelectedValue вашего myCombo и 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

Я просто понял, что это похоже, так что я думаю, что я хорошо думаю. Я попробую это. – MajkeloDev

1

Если я понимаю правильно, что вы хотите, чтобы справиться с SelectionChanged в ViewModel и внести некоторые изменения в itemsForListView1 и itemsForListView2 вместо того, что вы делаете в View в данный момент?

1) В ViewModel вам необходимо: создать общественную собственность ICommand, который может быть обработан, например, как 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) Вид, который вы хотите связать 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> 

Возможно, вы захотите использовать ObservableCollection вместо List, если ваша коллекция меняется, и вы хотите показать изменения в пользовательском интерфейсе. Вам необходимо реализовать INotifyPropertyChanged в любом случае, если вы собираетесь создавать новую коллекцию после изменения события с изменением.

+0

Аккупированный ответ делает то же самое, но проще, поэтому я принял его. В любом случае спасибо за ваш ответ. – MajkeloDev

Смежные вопросы