我有一个 ObservableCollection 对这个例子就是坐在一个WPF DataGrid.的 DataGrid 有三列:

  • 位置柱;这是呈现在运行时通过一个用户控件显示的位置排在我的数据表格
  • 名列;这是呈现在运行时通过一个用户控件,显示在名称一栏(是的,我需要一个用户控件为这个基础上,如何名称需要显示的,但这是一句)
  • 数据列;这是呈现在运行时通过的又一个用户控件.

我的列的定义是这样的:

        <toolkit:DataGrid.Columns>
            <toolkit:DataGridTemplateColumn Header="" MinWidth="35" MaxWidth="35" SortMemberPath="Position.PositionIndex" CanUserSort="True">
                <toolkit:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ContentPresenter Content="{Binding Path=Position}"/>
                    </DataTemplate>
                </toolkit:DataGridTemplateColumn.CellTemplate>
            </toolkit:DataGridTemplateColumn>
            <toolkit:DataGridTemplateColumn Header="Name" MinWidth="150" Width="150" SortMemberPath="Name" CanUserSort="True">
                <toolkit:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ContentPresenter Content="{Binding Path=Name}"/>
                    </DataTemplate>
                </toolkit:DataGridTemplateColumn.CellTemplate>
            </toolkit:DataGridTemplateColumn>
            <toolkit:DataGridTemplateColumn Header="Data" Width="Auto" CanUserSort="False">
                <toolkit:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ContentPresenter Content="{Binding Path=Data}"/>
                    </DataTemplate>
                </toolkit:DataGridTemplateColumn.CellTemplate>
            </toolkit:DataGridTemplateColumn>
        </toolkit:DataGrid.Columns>

所以,因为我排和名称列UserControls,WPF DataGrid 不能原本排序上的他们。所以,为便于分类,当一列的标题是点击,我做了一些 ListCollectionView.CustomSort 魔法。

这里是我定制的机看起来像的名称列:

// Customized sorter, by name, ascending.
public class AscendingNameSorter : IComparer
{
    public int Compare(object x, object y)
    {
        var lhs = (MyViewModel)x;
        var rhs = (MyViewModel)y;

        return lhs.Name.CompareTo(rhs.Name);
    }
}

// Customized sorter, by name, descending.
public class DescendingNameSorter : IComparer
{
    public int Compare(object x, object y)
    {
        var lhs = (MyViewModel)x;
        var rhs = (MyViewModel)y;

        return rhs.Name.CompareTo(lhs.Name);
    }
}

问题是这是 慢令人难以置信.我不知道为什么。有10个项目中的 DataGrid, 我应用程序陷入停顿的3-4秒钟,而这度假胜地。我以为 ListCollectionView.CustomSort 应该是最有效的方式进行排序 ObservableCollection...我要去哪里错了吗?

有帮助吗?

解决方案

WPF是重建所有的UserControls每次序的变化,因此我的猜测是什么东西在建设这些控制措施是缓慢的。但是,这只是一种猜测。

你应该开始通过缩小的问题。这里有一些可以采取的步骤:

  1. 找出哪些运作是把3到4秒钟。你没状态的延迟是否发生,只有当分配的价值CustomSort,或者每一个时间表的变化之后CustomSort已经确定。这有差别。

  2. 尝试增加一个常规的文本列和排序上使用建立在排序,看看它是否是快捷或者没有。也许你已经这样做了,但是你没有说在你的问题。

  3. 用于诊断目的的暂时停止设置CustomSort和设ListCollectionView.滤波器,而不是。它设为一个过滤器,总是返回正确的。如果你仍然得到经济放缓,该问题有关的ListCollectionView试图重新组织的项目。

  4. 暂时的编辑模板,并替换您的定义UserControls与一些微不足道(例如: <CheckBox/>)来看看事情的速度上升或没有。

  5. 设断点的构造你的UserControls看到,如果他们被称为预期的次数(即10构造的电话如果有的10个项目中的列表)。如果他们被称为更多的时间比预期的,看看这堆的痕迹看到那里的额外电话来了。

  6. 添加码到你的用户控件造写的日期时间。现在建设被称为输出窗口(或记录,或任何).这会给你一些想法如何长每。

  7. 添加几百项目到你ObservableCollection,运行程序side-by-side与VS.NET,点击你的按钮(或者),然后打破所有的按钮VS.NET 看看这堆踪。命中继续并立即打破所有的再次,然后看看那堆跟踪一次。重复多次。这会给你一个很好的想法是什么采取所有额外的时间。

如果我怀疑,问题是缓慢的UserControls建立的和有约束力的,你会发现:问题是发生在每一名单的改变,也会发生在你改变的过滤器,事情的速度,当你替换您的UserControls与 <CheckBox/>, ,您的构造只会被称为一旦每个项目之间的时间将相当大的.

注意,我不是说这是 构造 的UserControls是缓慢的可能的用户控件实例许多子对象时它的数据,或者它包括对象是缓慢的,或者复杂的,一个子对象负载一个文件,或许多其它可能的原因。底线是实例的数据模板上的目的和将它添加到这些树正在做一些缓慢的。堆的痕迹,应该让你知道哪里可以找到。

如果事实证明是别的东西或者你可以弄清楚,就更新你的问题给予更多的信息在什么上面测试显示,我们将尽力帮助你。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top