【问题标题】:Confused about CollectionViewSource (SelectedItem not working in combos)对 CollectionViewSource 感到困惑(SelectedItem 无法组合使用)
【发布时间】:2012-04-19 23:55:15
【问题描述】:

我有一堆组合,它们都有相同的可用选择。这些选择在我的 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 的设置器。

我显然遗漏了 CollectionView 应该如何工作的基础知识。任何人都可以启发我吗?

编辑:我的错,这确实适用于IsSynchronizedWithCurrentItem="False"。详情见我的回答。

干杯。

【问题讨论】:

  • 在 IsSynchronizedWithCurrentItem="False" 的解决方案中,您是否使用了 INotifyPropertyChanged? OnPropertyChanged("SelectedItem")

标签: c# wpf combobox selecteditem collectionviewsource


【解决方案1】:

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

至于为什么我需要明确关闭 IsSynchronizedWithCurrentItem,而我通常不会在标准集合上这样做,MSDN 上的亮点是@

true 如果 SelectedItem 始终与 ItemCollection 中的当前项同步; false 如果 SelectedItem 从未与当前项目同步; 仅当 Selector 使用 CollectionView 时,如果 SelectedItem 与当前项同步,则无。默认值为 Nothing。

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

【讨论】:

  • 我花了一整天的时间试图找出问题所在,这节省了我的晚上..非常感谢.. :)
【解决方案2】:

我有一段时间没有接触 WPF,但我认为您需要为每个组合框使用不同的 CollectionViewSource 实例来维护所选项目。

我认为这是因为SelectedItem 属性绑定到CollectionViewSource 对象的选定项状态属性(我猜View 对象具有它)并且ComboBoxes 都共享相同的源实例,因此他们选择的项目现在已同步。

因此,只需为每个 ComboBox 使用不同的 CollectionViewSource 实例。您仍然可以共享相同的来源选择。您只需要不同的虚拟机,因为您的 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 的元素。

【讨论】:

  • 非常感谢您的示例代码,但为每个组合排序一个新实例是不可行的。组合的数量是动态的,并且有很多。我想我只需要自己对集合进行排序并公开它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-27
  • 2015-01-21
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多