2011-08-25 46 views
0

实体框架提供了可追踪实体,这些实体具有名为ChangeTracker.State的属性。使用这个我们可以识别一个实体是否被删除。WPF CollectionViewSource.Filter性能对数据触发器

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

哪个更快?

方法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; 
} 

方法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> 

谢谢。

+0

几乎总是:找出你需要测量的更快。创建选项和度量。有太多的依赖我们看不到,因此几乎不可能给这类问题提供一个坚实的答案。 –

+0

是的,但是如何衡量XAML.DataTrigger的执行?因为我认为真正的测量几乎是不可能的,所以我从一个普遍的立场要求更多。 –

+0

当我们试图测量XAML行为之前,缺少“AllDone”事件几乎阻碍了我们准确的计划。 –

回答

0

方法1是正确的答案。

0

但是,加载事件可能有你需要的信息。从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次绑定到TextBlocks。我也会与XAML中定义的过滤器进行比较。我的直觉是两者都会变得如此之快,以至于很难了解其中的差异,但我猜想过滤器会更快。

+0

但是:Loaded事件在最终渲染之前引发! –

+0

正是。但是,如果过滤器和触发器在最终渲染之前得到处理,您可以比较两者,那就是您的问题。在布局系统计算出所有必要的渲染值之后,你如何解释?很有可能过滤器和触发器在“计算所有必需的值”内。对不起,我试图帮助! – Paparazzi

2

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

原因...

  1. 其过滤是在视图模型的手中。所以无论何时想刷新收藏视图,它都会重新过滤。

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

  3. 交替项目此CollectionView所应用的ItemsControl的行样式不会对数据触发器产生正确的影响,因为它只会隐藏项目并且不会调整交替行样式,但collectionview会事先排除项目本身。即如果交替行需要灰色背景,那么如果使用DataTrigger,则可能发生两个相邻行将灰色。

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

CollectionView提供了50个项目来滚动视图之前的手本身。

因此,就性能而言,DataTrigger会更快,这是因为仅当该项目被解除虚拟化时,即在滚动视图中引入时才会应用DataTrigger。但它可能会造成上述问题。

让我知道这是否有帮助。