C# 对CollectionViewSource感到困惑(SelectedItem不在组合中工作)

C# 对CollectionViewSource感到困惑(SelectedItem不在组合中工作),c#,wpf,combobox,selecteditem,collectionviewsource,C#,Wpf,Combobox,Selecteditem,Collectionviewsource,我有很多组合,它们都有相同的可用选择。这些选项在从my ViewModel公开的集合中提供。一切都很好 我现在希望对这些选项进行排序,因此我决定从我的ViewModel中公开一个ICollectionView,而不是我通常的ReadonlyObservableCollection,并在我的ViewModel中对集合视图进行排序 class EditStuffViewModel : ViewModelBase { public EditStuffViewModel (ObservableC

我有很多组合,它们都有相同的可用选择。这些选项在从my ViewModel公开的集合中提供。一切都很好

我现在希望对这些选项进行排序,因此我决定从我的ViewModel中公开一个
ICollectionView
,而不是我通常的
ReadonlyObservableCollection
,并在我的ViewModel中对集合视图进行排序

class EditStuffViewModel : ViewModelBase
{
    public EditStuffViewModel (ObservableCollection<Choice> choices)
    {
        Choices = new CollectionViewSource() { Source = choices }.View;
        Choices.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
    }

    public ICollectionView Choices
    {
        get;
        private set;
    }

    //snip other properties
}
类EditStuffViewModel:ViewModelBase { public EditStuffViewModel(ObservableCollection选项) { Choices=new CollectionViewSource(){Source=Choices}.View; Choices.SortDescriptions.Add(新的SortDescription(“Name”,ListSortDirection.升序)); } 公共ICollectionView选项 { 得到; 私人设置; } //剪掉其他财产 } 这一切都很好,只是现在我的所有组合都同步它们的选择

这不是我想要的。我希望共享选择,但选择要与它们的正常绑定一致。我想我知道我的CollectionView正在跟踪选择,但我认为这是每个控件的选择

我已尝试在组合上显式设置
IsSynchronizedWithCurrentItem=“False”
,成功地将它们解耦,但组合中从未选择我的绑定
SelectedItem
(调用ViewModel的绑定获取程序,但从未选择结果)。选择一个项目似乎可以正确地更新我的ViewModel的setter

我显然遗漏了CollectionView应该如何工作的一些基本内容。谁能启发我

编辑:我的错,这个不适用于
IsSynchronizedWithCurrentItem=“False”
。有关详细信息,请参阅我的答案


干杯。

我已经有一段时间没有碰过WPF了,但我认为您需要为要维护的选定项目的每个组合框使用不同的
CollectionViewSource
实例

我认为这是因为
SelectedItem
属性被绑定到
CollectionViewSource
对象的selected item state属性(我猜
View
对象有它)和组合框都共享同一个源实例,因此它们所选的项现在被同步

因此,只需为每个组合框使用不同的
CollectionViewSource
实例即可。您仍然可以共享相同的源选择。您只需要不同的VM,因为您的组合框应该彼此独立


类似这样(未经测试):

类EditStuffViewModel:ViewModelBase { public EditStuffViewModel(ObservableCollection选项) { ChoiceViews=新列表(); 对于(变量i=0;i<10;i++){ var viewSource=new CollectionViewSource(){Source=choices}; 添加(新的SortDescription(“Name”,ListSortDirection.升序)); ChoiceViews.Add(viewSource.View); } } 公众意见 { 获得;私人设置; } //剪掉其他财产 }
然后将您的组合框绑定更改为绑定到
ChoiceViews
的元素。

很抱歉浪费了大家的时间,但是设置
IsSynchronizedWithCurrentItem=“False”
确实有效。我还添加了一个过滤器和排序,默认选择的值不在过滤的项目列表中。哎呀

至于为什么我需要显式地关闭IsSynchronizedWithCurrentItem,而我通常在标准集合上从来没有这样做过,这一点很清楚

true如果SelectedItem始终与ItemCollection中的当前项同步false如果SelectedItem从未与当前项目同步仅当选择器使用CollectionView时,如果SelectedItem与当前项同步,则不执行任何操作。默认值为零。


因此,换句话说,如果您显式地使用
CollectionView
而不是在普通集合上使用默认视图,您将获得选择同步。

非常感谢您的示例代码,但无法为每个组合排序新实例。组合的数量是动态的,而且有很多组合。我想我只需要自己对集合进行一次排序并将其公开。在使用IsSynchronizedWithCurrentItem=“False”的解决方案中,是否使用INotifyPropertyChanged?在PropertyChanged(“SelectedItem”)上,我花了一整天的时间试图找出问题所在,这节省了我的晚上。。非常感谢……)
class EditStuffViewModel : ViewModelBase
{
    public EditStuffViewModel (ObservableCollection<Choice> choices)
    {
        ChoiceViews = new List<ICollectionView>();

        for (var i = 0; i < 10; i++) {
            var viewSource = new CollectionViewSource() { Source = choices };
            viewSource.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));

            ChoiceViews.Add(viewSource.View);
        }
    }

    public IList<ICollectionView> ChoiceViews
    {
        get; private set;
    }

    //snip other properties
}