与 CollectionViewSource 绑定
我正在尝试使用 CollectionViewSource 实现一些组合框排序。该组合框实际上是数据模板的一部分,并在列表视图中重复出现。我的第一种方法似乎有效(使用 CollectionViewSource),但我的所有组合框共享相同的数据上下文。这使得每当其他盒子之一发生变化时,所有其他盒子都会发生变化以反映 - 这不是期望的副作用。
我决定回过头来尝试使用内联 xaml 来指定 CollectionViewSource(而不是将 cvs 创建为静态资源)来实现基本组合框(不在数据模板内)。我无法成功显示我的数据。我的想法可能完全错误,因为我对 WPF 还很陌生。
下面是我的组合框的 xaml:
<ComboBox>
<ComboBox.ItemsSource>
<Binding>
<Binding.Source>
<CollectionViewSource Source="{Binding Path=Configurations}">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="AgencyName" />
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</Binding.Source>
</Binding>
</ComboBox.ItemsSource>
</ComboBox>
此组合框所在的用户控件的 DataContext 绑定到一个对象,该对象具有名为 Configurations 的 ObservableCollection,并且每个配置都有一个名为 AgencyName 的属性。我已经验证,使用没有 cvs 的标准绑定可以正常工作,所以我知道一切都很好。
任何帮助将不胜感激,因为我已经没有借口给我的老板了:)。我也不想进入代码并在后面的代码中进行排序(当我构建 ObservableCollection 时我可以这样做,但恕我直言,这违反了 DRY 原则)。
I am trying to implement some combo box sorting using CollectionViewSource. This combo box is actually part of a data template and is repeated in a list view. My first approach seemed to work (using CollectionViewSource) but all my combo boxes shared the same data context. This made it so whenever one of the other boxes was changed all the others changed to reflect - not a desired side effect.
I decided to just pull back and try to implement a basic combo box (not inside a data template) using inline xaml for specifying the CollectionViewSource (as opposed to creating the cvs as a static resource). I have not been able to successfully get my data to display. I'm probably going about this entirely wrong as I'm still new to WPF.
Here is the xaml for my combo box:
<ComboBox>
<ComboBox.ItemsSource>
<Binding>
<Binding.Source>
<CollectionViewSource Source="{Binding Path=Configurations}">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="AgencyName" />
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</Binding.Source>
</Binding>
</ComboBox.ItemsSource>
</ComboBox>
The DataContext of the user control where this combo box lives is bound to an object which has an ObservableCollection called Configurations and each configuration has a property called AgencyName. I've verified that this works fine using standard binding without the cvs so I know everything is fine in that accord.
Any help would be greatly appreciated as I have ran out of excuses to my boss :). I also don't want to have to drop down into code and do the sorting in the code behind (which I could when I build the ObservableCollection but IMHO that violates the DRY principle).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
“每当其他盒子之一发生变化时,所有其他盒子都会发生变化以反映”到底是什么意思?您是在谈论 SelectedItem 吗?
如果是这样,那么在 ComboBox 中设置
IsSynchronizedWithCurrentItem = false
可能会有所帮助。除此之外:我认为只要您在后面的代码中创建并排序 ICollectionView 一次,就不会违反 DRY 原则,因为您在 XAML 中不再需要做更多的事情。但我发现可能还有其他原因说排序等功能应该在视图中完成,从模型-视图-视图模型的角度来说。
What exactly do you mean by "whenever one of the other boxes was changed all the others changed to reflect"? Are you talking about the SelectedItem?
If so, then it may help setting
IsSynchronizedWithCurrentItem = false
in your ComboBox.Beside that: I think as long as you create and sort your ICollectionView in the code behind only once, there is no violation of the DRY principle, because what you do more there is not needed in the XAML anymore. But I see there may be other reasons to say that a feature like sorting should be done in the View, speaking in terms of Model-View-ViewModel.
没有阅读您的整篇文章,但问题是默认情况下资源是共享的。因此,每个组合框都引用相同的集合视图。集合视图包括跟踪选择,因此更改一个组合框中的选择会影响其他组合框中的选择。
您可以阻止 CVS 被共享,而不是将 CVS 移至本地资源:
Didn't read your entire post, but the problem is that resources are shared by default. Each combo box was therefore referencing the same collection view. A collection view includes tracking selection, so changing the selection in one combo box would affect the others.
Rather than move the CVS to a local resource, you could just prevent it from being shared:
虽然可能为时已晚,但我将这个答案留给可能遇到此问题的其他人。
您对 CollectionViewSource.Source 的绑定不起作用,因为 CollectionViewSource 不属于视觉/逻辑树,并且它既不继承数据上下文,也不能够引用 ComboBox 作为绑定源。我能够使用以下类以一种丑陋但简单的方式解决这个问题:
这是一个用法示例(未显示资源字典):
While its probably too late, I'm leaving this answer for others who may encounter this problem.
Your binding for the CollectionViewSource.Source doesn't work because the CollectionViewSource doesn't belong to the visual/logical tree, and it neither inherits the Data Context nor its able to reference the ComboBox as a source of binding. I was able to solve this in an ugly, but simple way using the following class:
Here is an example of usage (the resource dictionary isn't shown):
绑定依赖于 VisualTree,而 cvs 不是视觉对象,因此绑定不起作用。
您可以使用 x:Reference 代替。
Binding depends on VisualTree which cvs is not a visual, so Binding doesn't work.
You can use x:Reference instead.