0

实体框架提供具有名为 ChangeTracker.State 的属性的可跟踪实体。使用它我们可以识别实体是否被删除。

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

哪个更快?

方法一:使用 CollectionViewSource.Filter 测试并移除 Record

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

方法二:在ItemTemplate.DataTemplate中添加DataTrigger来测试隐藏Item

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

谢谢。

4

3 回答 3

2

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

原因...

  1. 它的过滤在 ViewModel 手中。因此,每当它想要刷新集合视图时,它都会再次重新过滤。

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

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

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

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

因此,就性能而言,正是由于这一点,DataTrigger 将更快,因为它仅在项目被去虚拟化时应用,即被引入滚动视图。但它可能会带来上述问题。

让我知道这是否有帮助。

于 2011-08-26T08:00:34.053 回答
0

但是 Loaded 事件可能包含您需要的信息。来自 MSDN:Loaded 事件在最终渲染之前引发,但在布局系统计算出所有必要的渲染值之后。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 中定义的过滤器进行比较。我的直觉是两者都将如此之快以至于很难知道区别,但我猜过滤器更快。

于 2011-08-25T17:13:20.027 回答
0

方法一是正确答案。

于 2011-09-07T20:14:29.613 回答