对CollectionViewSource感到困惑(SelectedItem在组合框中不起作用)
本文关键字:组合 不起作用 SelectedItem CollectionViewSource | 更新日期: 2023-09-27 18:30:08
我有一堆组合,它们共享相同的可用选项。这些选择是在我的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应该如何工作的一些基本内容。有人能启发我吗?
编辑:我的错,这个确实适用于IsSynchronizedWithCurrentItem="False"
。有关详细信息,请参阅我的回答。
干杯。
很抱歉浪费了大家的时间,但设置IsSynchronizedWithCurrentItem="False"
确实有效。我在排序的同时还添加了一个过滤器,默认选择的值不在筛选的项目列表中。哎呀。
至于为什么我需要明确地关闭IsSynchronizedWithCurrentItem,而我通常从不在标准集合上这样做,MSDN 上有一些线索
true如果SelectedItem始终与ItemCollection中的当前项同步false如果SelectedItem从未与当前项目同步仅当Selector使用CollectionView时,SelectedItem才与当前项同步,则为Nothing。默认值为Nothing
换句话说,如果显式使用CollectionView
,而不是在普通集合上使用默认视图,则可以获得选择同步。
我已经有一段时间没有接触过WPF了,但我认为对于要维护的所选项目,每个组合框都需要不同的CollectionViewSource
实例。
我认为这是因为SelectedItem
属性被绑定到CollectionViewSource
对象的选定项目状态属性(我猜View
对象有它),并且ComboBoxes都共享同一个源实例,因此它们的选定项目现在是同步的。
因此,只需为每个组合框使用不同的CollectionViewSource
实例即可。您仍然可以共享相同的源选项。您只需要不同的虚拟机,因为您的组合框应该彼此独立。
类似的东西(未经测试):
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
的元素。