WPF CollectionViewSource.Filter性能v。数据触发器

WPF CollectionViewSource.Filter性能v。数据触发器,wpf,datatrigger,collectionviewsource,Wpf,Datatrigger,Collectionviewsource,实体框架提供可跟踪的实体,这些实体具有名为ChangeTracker.State的属性。使用此选项,我们可以确定是否删除了实体 在我们的列表中,我们不希望显示已删除的实体 哪个更快 方法1:使用CollectionViewSource.Filter测试并删除记录 <CollectionViewSource Filter="ViewSource_Filter" /> private void ViewSource_Filter(object sender, FilterEventAr

实体框架提供可跟踪的实体,这些实体具有名为ChangeTracker.State的属性。使用此选项,我们可以确定是否删除了实体

在我们的列表中,我们不希望显示已删除的实体

哪个更快

方法1:使用CollectionViewSource.Filter测试并删除记录

<CollectionViewSource Filter="ViewSource_Filter" />

private void ViewSource_Filter(object sender, FilterEventArgs e)
{
    var _Item = e.Item as ITrackableEntity;
    e.Accepted = _Item.ChangeTracker.State != ObjectState.Deleted;
}

私有void ViewSource_筛选器(对象发送方、筛选器目标方)
{
var_Item=e.作为ITrackableEntity的项目;
e、 已接受=\u Item.ChangeTracker.State!=ObjectState.Deleted;
}
方法2:将DataTrigger添加到ItemTemplate.DataTemplate以测试和隐藏项目

<DataTemplate.Resources>
    <Style TargetType="{x:Type DockPanel}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding ChangeTracker.State}">
                <DataTrigger.Value>
                    <entities:ObjectState>Deleted</entities:ObjectState>
                </DataTrigger.Value>
                <Setter Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</DataTemplate.Resources>

删除

谢谢。

但是加载的事件可能包含您需要的信息。来自MSDN:加载的事件在最终渲染之前,但在布局系统计算了渲染所需的所有值之后引发。Loaded意味着包含元素的逻辑树是完整的,并连接到提供HWND和渲染表面的表示源。我的解释是,过滤器和触发器已经处理,但我不是肯定的。这不是一个最终的数字,但我认为你会比较苹果和苹果。但苹果可能不是正确的比较。如果调试器能够遍历XAML,那就太好了。由于调试器不会遍历XAML,我认为您无法直接测量触发器。最好的希望是测量页面。创建一个只有困难过滤器的页面

    public MainWindow()
    {
        Debug.WriteLine(DateTime.Now.ToLongTimeString());
        InitializeComponent();
        Debug.WriteLine(DateTime.Now.ToLongTimeString());
    }

    private void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        Debug.WriteLine(DateTime.Now.ToLongTimeString());

调试与直接执行不同,因此我会将这3次绑定到文本块。我还将与XAML中定义的过滤器进行比较。我的直觉是,两者的速度都会非常快,很难知道它们之间的区别,但我猜过滤器会更快。

假设这个问题涉及到ItemsControl,我个人喜欢基于collectionview的过滤器

原因

  • 它的过滤由ViewModel负责。因此,每当它想要刷新集合视图时,它都会再次重新过滤

  • 如果
    ChangeTracker.State
    属性仅在UI的整个生命周期内填充且未更新,则集合视图在呈现时仅过滤一次。另一方面,DataTriggers将等待对
    ChangeTracker.State
    的任何更改,这些更改可能/可能不会发生

  • 应用此CollectionView的Items控件的交替项行样式将不会在数据触发器中正确生效,因为它只会隐藏项,而不会调整交替行样式,但CollectionView本身会事先排除项。i、 e.如果备用行需要为灰色背景,则如果使用DataTrigger,则相邻两行可能为灰色

  • DataTriggers将仅对非虚拟化的项目生效,因为滚动条启发式可能会出错,例如,如果滚动视图仅显示10个可见项目,并且源中有90个项目,但有50个项目处于
    已删除
    状态,则除非我们滚动到它们,否则它们的数据触发器将不会生效。因此在此期间,滚动条将重新计算并闪烁以调整其实际滚动值。因此,它可能会像我们有100个项目适用于滚动,而实际上它只需要50个项目滚动到

  • CollectionView提供了50个项目,可在手动之前滚动查看

    正因为如此,就性能而言,DataTrigger将更快,因为只有在项目被非虚拟化时(即在滚动视图中)才会应用。但它可能会带来上述问题


    让我知道这是否有帮助。

    方法1是正确答案。

    但是:加载的事件在最终渲染之前引发!确切地但是,如果过滤器和触发器是在最终渲染之前处理的,那么您将得到两者的比较,这就是您的问题。如何解释“在布局系统计算了渲染所需的所有值之后”?很可能过滤器和触发器在“计算出的所有必要值”范围内。对不起,我想帮忙!几乎总是这样:为了找出什么更快,你需要测量。创建选项和度量值。我们看不到太多的依赖关系,因此几乎不可能对这类问题给出可靠的答案。是的,但如何衡量XAML.DataTrigger的执行情况?我从一般的立场上要求更多,因为我认为真正的测量几乎是不可能的。当我们以前尝试测量XAML行为时,缺少一个“完成”事件几乎阻碍了我们的准确计划。如果你不能测量差异,你为什么要担心它?我通常会说,如果还使用排序和分组,则DataTrigger会更快。