Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 组合框选择在MVVM中更改_C#_Wpf_Mvvm - Fatal编程技术网

C# 组合框选择在MVVM中更改

C# 组合框选择在MVVM中更改,c#,wpf,mvvm,C#,Wpf,Mvvm,我有一个WPF中没有MVVM的应用程序,我决定将其重构为MVVM。我遇到组合框SelectionChanged事件的问题。基本上,为了使它更简单,让我们假设我有一个组合框和两个ListView。每个ComboBoxItem都是一个集合。第一个ListView的ItemsSource绑定到ComboBox.SelectedValue中的集合,但仅绑定到decimal的一个属性大于零的部分。第二个ListView的ItemsSource绑定到同一个collection,但绑定到第二个part的某些属

我有一个WPF中没有MVVM的应用程序,我决定将其重构为MVVM。我遇到组合框SelectionChanged事件的问题。基本上,为了使它更简单,让我们假设我有一个组合框和两个ListView。每个ComboBoxItem都是一个集合。第一个ListView的ItemsSource绑定到ComboBox.SelectedValue中的集合,但仅绑定到decimal的一个属性大于零的部分。第二个ListView的ItemsSource绑定到同一个collection,但绑定到第二个part的某些属性大于零。下面有一些代码可以理解

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

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

我建议使用下面的伪代码解决方案。将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);
        }
    }
}

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

如果我理解正确,您希望的是处理ViewModel中更改的选择,并对itemsForListView1和itemsForListView2进行一些更改,而不是对您目前在View中所做的操作进行更改

1在ViewModel中,您需要:创建ICommand公共属性,该属性可以实例化为Microsoft.Practices.Composite.Presentation.Commands中的DelegateCommand:

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>

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

如果我理解正确,则需要在ViewModel中处理SelectionChanged,并对itemsForListView1和itemsForListView2进行一些更改,而不是更改当前在View中执行的操作什么时候

1在ViewModel中,您需要:创建ICommand公共属性,该属性可以实例化为Microsoft.Practices.Composite.Presentation.Commands中的DelegateCommand:

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>

如果您的集合正在更改,并且希望在UI上显示更改,则可能需要使用ObservableCollection而不是List。如果要在选择更改事件后创建新集合,则需要实现INotifyPropertyChanged(INotifyPropertyChanged)。将此事件方法设置为可自行提升的属性,并使用进一步的属性与ListView绑定。我对MVVM非常陌生,因此我希望通过进一步的描述了解exmaple使用此事件方法我对MVVM还很陌生,所以我想我可能会有一些更详细的描述。我刚刚发现了一些类似的东西,所以我想我的想法很好。我会试试这个。我刚刚发现了一些相似的东西,所以我想我的思维方式很好。我会试试这个。认可的答案也一样,但更简单,这就是我接受它的原因。不管怎样,谢谢你的回答。认可的答案也一样,但更简单,这就是我接受它的原因。无论如何,谢谢你的回答。