C# 在WPF中,您可以在没有代码隐藏的情况下过滤CollectionViewSource吗?

C# 在WPF中,您可以在没有代码隐藏的情况下过滤CollectionViewSource吗?,c#,wpf,xaml,filter,collectionviewsource,C#,Wpf,Xaml,Filter,Collectionviewsource,事实上,这个主题说明了一切 <CollectionViewSource x:Key="MyData" Source="{Binding}" Filter="{ SomethingMagicInXaml? }" /> 并不是说我不能把代码隐藏起来。这让我很恼火。如果你“足够努力”,你几乎可以在XAML中做任何事情 您将永远无法避免代码落后(如果您使用库,您不必编写任何代码,但应用程序仍然依赖于它),下面是一个示例,说明在这种特定情况下您可以做什么: <Collect

事实上,这个主题说明了一切

<CollectionViewSource x:Key="MyData"
    Source="{Binding}" Filter="{ SomethingMagicInXaml? }" />


并不是说我不能把代码隐藏起来。这让我很恼火。

如果你“足够努力”,你几乎可以在XAML中做任何事情

您将永远无法避免代码落后(如果您使用库,您不必编写任何代码,但应用程序仍然依赖于它),下面是一个示例,说明在这种特定情况下您可以做什么:

<CollectionViewSource x:Key="Filtered" Source="{Binding DpData}"
                      xmlns:me="clr-namespace:Test.MarkupExtensions">
    <CollectionViewSource.Filter>
        <me:Filter>
            <me:PropertyFilter PropertyName="Name" Value="Skeet" />
        </me:Filter>
    </CollectionViewSource.Filter>
</CollectionViewSource>
如果您想在XAML中做一些事情,标记扩展是您的朋友

(您可能需要详细说明扩展名,即
me:FilterExtension
,因为在Visual Studio中进行的动态签入可能会无缘无故地抱怨,它当然仍会编译并运行,但警告可能会令人讨厌。

也不要期望IntelliSense中显示
CollectionViewSource.Filter
,它不希望您通过XML元素表示法设置该处理程序)

实际上您甚至不需要访问
CollectionViewSource
实例,您可以直接在ViewModel中过滤源集合:

ICollectionView view = CollectionViewSource.GetDefaultView(collection);
view.Filter = predicate;

(请注意,
ICollectionView.Filter
CollectionViewSource.Filter
不同,它是
谓词类型的属性)

WPF自动创建一个或一个派生类型,例如
ListCollectionView
,或
BindingListCollectionView
-当您将任何
IEnumerable
派生的源数据绑定到
ItemsControl.ItemsSource
属性时。获得哪种类型的
CollectionView
取决于在运行时检测到的数据源功能

有时,即使您尝试将自己特定的
CollectionView
派生类型显式绑定到
ItemsSource
,WPF数据绑定引擎也可能会将其包装(使用内部类型
CollectionViewProxy

自动提供的
CollectionView
实例由系统根据每个集合创建和维护(注意:不是每个集合)- 用户界面控件或每- 绑定目标)。换句话说,您绑定到的每个s̲o̲u̲r̲c̲e̲集合将只有一个全局共享的“默认”视图,并且可以随时通过传递相同的“原始”来检索(或根据需要创建)此唯一的
CollectionView
实例
IEnumerable
实例返回静态方法
CollectionViewSource。​再次执行GetDefaultView()

CollectionView
是一个垫片,它能够跟踪排序和/或筛选状态,而不会实际更改源。因此,如果相同的源数据被多个不同的
绑定所引用,每个
使用不同的
集合视图
,则它们不会相互干扰。“默认”视图旨在优化不需要或不期望进行筛选和排序的非常常见且更简单的情况

简言之,每个带有数据绑定的
ItemsSource
属性的
ItemsControl
最终都将具有排序和筛选功能,这得益于一些流行的
CollectionView
。通过从
ItemsControl.Items
属性中抓取并操作“Default”
CollectionView
,您可以轻松地对任何给定的
IEnumerable
执行筛选/排序,但请注意,UI中最终使用该视图的所有数据绑定目标——要么因为您显式绑定到
CollectionViewSource.GetDefaultView()
,要么因为您的源代码根本不是
CollectionView
——都将共享相同的排序/过滤效果

在这个主题中不经常提到的是,除了将源集合绑定到
ItemsControl
ItemsSource
属性(作为绑定目标)之外,还可以“同时”通过从控件的
属性(作为绑定源)绑定,访问所应用筛选/排序结果的有效集合——作为
集合视图
的派生实例公开

这支持许多简化的XAML场景:

  • 如果对给定的
    IEnumerable
    源具有一个全局共享的筛选/排序功能就足以满足应用程序的需要,那么只需直接绑定到
    ItemsSource
    。仍然只在XAML中,您可以通过
    items
    属性作为绑定源处理在同一控件上,对项目进行过滤/排序。它有许多有用的可绑定属性用于控制过滤器/排序。如上所述,过滤/排序将以这种方式在绑定到同一源
    IEnumerable
    的所有UI元素之间共享。或者--

  • 自己创建并应用一个或多个不同的(非“默认”)
    CollectionView
    实例。这允许每个数据绑定目标具有独立的筛选/排序设置。这也可以在XAML中完成,和/或您可以创建自己的
    (列表)CollectionView
    派生类。这种类型的方法在其他地方有很好的介绍,但我想在这里指出的是,在许多情况下,可以通过使用与
    ItemsControl.Items
    属性
    (作为绑定源)相同的数据绑定技术来简化XAML,以便访问有效的
    集合视图


  • 摘要:

    仅使用XAML就可以将数据绑定到一个集合,该集合表示WPF
    项控件的任何当前
    集合视图
    过滤/排序的有效结果,方法是将其
    属性视为只读绑定。这将是一个
    System.Windows.Controls.ItemCollection
    ,它公开了bindable/mutable pro