对CollectionViewSource感到困惑(SelectedItem在组合中不起作用)

时间:2012-04-06 10:24:29

标签: c# wpf combobox selecteditem collectionviewsource

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

我现在想要对这些选择进行排序,因此我决定从我的ViewModel而不是通常的ICollectionView中公开ReadonlyObservableCollection<T>,并在我的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
}

这一切都运行正常,但现在我的所有组合现在同步他们的选择

这不是我想要的。我想要共享选择,但选择是他们的正常绑定。我想我明白我的CollectionView正在跟踪选择,但我认为这是每个控件的行为选择。

我已经尝试在我的组合上明确设置IsSynchronizedWithCurrentItem="False",它们成功地将它们解耦,但是我的绑定SelectedItem从未在组合中被选中(ViewModel的绑定getter被调用但结果从未被选中) 。选择一个项似乎确实正确地更新了我的ViewModel的setter。

我显然缺少了CollectionView应该如何运作的基本功能。任何人都可以开导我吗?

编辑:我的不好, DOES IsSynchronizedWithCurrentItem="False"合作。有关详细信息,请参阅我的回答。

干杯。

2 个答案:

答案 0 :(得分:4)

我很遗憾浪费每个人的时间,但设置IsSynchronizedWithCurrentItem="False"确实有用。我还添加了一个过滤器以及排序,默认选择的值不在过滤的项目列表中。糟糕。

至于为什么我需要明确地关闭IsSynchronizedWithCurrentItem,因为我从来没有在标准集合上做过,所以MSDN

  如果SelectedItem始终与ItemCollection中的当前项同步,则

true ;如果SelectedItem从未与当前项同步,则 false ; 仅当Selector使用CollectionView时,SelectedItem才与当前项同步。默认值为Nothing。

换句话说,如果您明确使用CollectionView而不是使用普通集合上的默认视图,则会获得选择同步。

答案 1 :(得分:0)

我暂时没有触及WPF,但我认为每个组合框需要CollectionViewSource的不同实例才能维护所选项目。

我认为这是因为SelectedItem属性绑定到CollectionViewSource对象的选定项状态属性(我猜测View对象有它)和组合框全部共享相同的源实例,因此他们所选的项目现在已同步。

因此,只需为每个ComboBox使用CollectionViewSource的不同实例。您仍然可以共享相同的源选择。您只需要不同的VM,因为您的ComboBox应该彼此分开。


像这样(未经测试):

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
}

然后将您的ComboBoxes绑定更改为绑定到ChoiceViews的元素。