传递非静态参数以在CollectionViewSource

时间:2019-03-16 23:49:14

标签: wpf xaml data-binding wpf-controls

在我的应用程序中,我有一个类似数据库的结构,其中数据库对象本身包含几个ObservableCollection<KeyValuePair<Guid, T>>集合。 Guid的作用类似于关系数据库中的主键,即,它们在不同集合的对象(数据库中的“表”)之间提供1:1和1:n映射。

现在考虑绑定ObservableCollection<KeyValuePair<Guid, T>>中位于对象层次结构根的ItemsControl。在DataTemplate内,我想将另一个集合的子集绑定到DependencyProperty的{​​{1}},其中UserControl匹配第一个集合中每个对象都携带的值。

正如我在此处的大量答案所暗示的,Guid是我所需要的,即

CollectionViewSource

但是,我需要将<ItemsControl ItemsSource="{Binding RootObjectCollection}> <ItemsControl.ItemTemplate> <DataTemplate> <local:CustomUserControl> <local:CustomUserControl.SubsetCollection> <Binding> <Binding.Source> <CollectionViewSource Source="{Binding DataContext.Database.SubsetCollection, RelativeSource={RelativeSource AncestorType=UserControl}}" Filter="someFilter" ???? FilterParameters="{Binding SelectedKeys}" /> </Binding.Source> </Binding> </local:CustomUserControl.SubsetCollection> </local:CustomUserControl> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> 类型的参数动态传递给ObservableCollection<Guid>的过滤器。

坦率地说,我迷路了,因为文档上没有任何内容。我不敢相信我是第一个需要不绑定到文本字段的参数化动态过滤器的人。任何提示都将不胜感激!

更新2019-03-18

上面的代码现在应该更加清晰了。除此之外,还提供了一些其他背景信息,以阐明@erotavlas的问题:

  • 上面的代码位于一个视图中,该视图具有自己的视图模型作为数据上下文。在CollectionViewSource中实例化的CustomUserControl也具有自己的视图模型。我上面尝试的是将过滤器结果(是基于DataTemplate当前SubsetCollection元素中包含的主键指示符的ItemControl的子集)传递给{{1 }}的对应字段。

  • 所有RootObjectCollection都位于名为CustomUserControl的对象的周围视图的视图模型中。此对象包含其中一些ObservableCollection,以及其他DatabaseObservableCollections

2 个答案:

答案 0 :(得分:0)

  

但是,我需要将ObservableCollection<Guid>类型的参数动态传递给CollectionViewSource的过滤器。

CollectionViewSource.Filter是一个事件,您不能向其传递任何自定义参数。您将获得一个FilterEventArgs,它具有对该项目的只读引用和一个Accepted属性,您可以设置该属性以指示是否在过滤后的集合中包含该项目,仅此而已。

您也许可以考虑创建一个扩展CollectionViewSource的类并添加您自己的自定义dependency property。这将使您能够绑定到SelectedKeys之类的源属性。然后,您可以通过在sender事件处理程序中转换Filter参数来检索依赖项属性的值,例如:

private void Cvs_Filter(object sender, FilterEventArgs e)
{
    YourCustomCollectionViewSource cvs = sender as YourCustomCollectionViewSource;
    //..
}

答案 1 :(得分:0)

当我发布此问题时,我很着急,因为只有几天没来得及进行非常重要的演示(产品融资)。由于我无法弄清楚如何使用CollectionViewSource解决问题,因此我决定尝试使用旧的MultiValueConverter方法解决方案,同时充分意识到这将使我创建新的{{ 1}}子集集合的值,根据C# man page for ObservableCollection<T>(IEnumerable<T>),它只能单向工作,因为“将元素复制到ObservableCollection上”。我认为最好是显示视图是从数据库填充的,而不是将更改反映回数据库,而不是什么都不显示。

当我发现手册页在这里并不完全正确时,我会感到惊讶:仅复制原始值,将复杂的对象通过引用传递到新的ObservableCollection<T>中!这意味着以下代码段是对我的问题的完全有效的解决方案:

ObservableCollection<T>

这里的重要部分是<ItemsControl ItemsSource="{Binding RootObjectCollection}> <ItemsControl.ItemTemplate> <DataTemplate> <local:CustomUserControl> <local:CustomUserControl.SubsetCollection> <MultiBinding Converter="{StaticResource SubsetEntryFromRootObjectIdSelectionConverter}"> <Binding Path="Value.SubsetIds" /> <Binding Path="DataContext.Database.SubsetCollection" RelativeSource="{RelativeSource AncestorType=UserControl}" /> </MultiBinding> </local:CustomUserControl.SubsetCollection> </local:CustomUserControl> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> 本身,它定义为

MultiValueConverter

由于此解决方案可以正常工作,因此我没有实施the one suggested by @mm8 above。但是,从技术上来讲,建议的解决方案是对我问题的直接回答,而我的坦白是一个解决方法。因此,我会接受@ mm8的回答,而不是我的回答。