gpt4 book ai didi

wpf - 为什么 ListCollectionView.CustomSort 这么慢?

转载 作者:行者123 更新时间:2023-12-03 10:24:52 24 4
gpt4 key购买 nike

我有一个 ObservableCollection位于 WPF 中的 ViewModel DataGrid . DataGrid有三列:

  • 职位栏;这是在运行时由 UserControl 呈现的,它显示我的 DataGrid
  • 中行的位置
  • 名称栏;这是在运行时由显示列名称的 UserControl 呈现的(是的,我需要一个基于名称需要显示方式的 UserControl,但这是一个旁白)
  • 数据栏;这是在运行时由另一个 UserControl 呈现的。

  • 我的列定义如下:
            <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>

    所以,因为我的 Row 和 Name 列是 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);
    }
    }

    问题是这是 非常慢 .我不知道为什么。 DataGrid 中有 10 项,我的应用程序在使用时会停止 3-4 秒。我以为 ListCollectionView.CustomSort应该是对 ObservableCollection 进行排序的最有效方法......我哪里错了?

    最佳答案

    每次排序更改时,WPF 都会重新创建所有用户控件,所以我的猜测是这些控件的构建过程很慢。但这只是一个猜测。

    您应该从缩小问题范围开始。以下是您可以采取的一些步骤:

  • 找出哪个操作需要 3-4 秒。您没有说明延迟是仅在将值分配给 CustomSort 时发生,还是在设置 CustomSort 后每次列表更改时发生。这会有所不同。
  • 尝试添加一个常规文本列并使用内置排序对其进行排序,以查看它是否快速。也许您已经这样做了,但是您没有在问题中说。
  • 出于诊断目的,暂时停止设置 CustomSort 并改为设置 ListCollectionView.Filter。将其设置为始终返回 true 的过滤器。如果仍然出现减速,则问题与 ListCollectionView 尝试重新组织项目有关。
  • 暂时编辑您的模板并用一些琐碎的东西(例如 <CheckBox/> )替换您的自定义用户控件,看看事情是否加快了速度。
  • 在 UserControls 的构造函数中设置断点以查看它们是否被调用了预期的次数(即,如果列表中有 10 个项目,则调用 10 个构造函数)。如果它们被调用的次数比预期的多,请查看堆栈跟踪以查看额外调用的来源。
  • 将代码添加到您的 UserControl 构造函数以编写 DateTime。现在构造函数被调用到输出窗口(或日志,或其他)。这会让你知道每个需要多长时间。
  • 将数百个项目添加到您的 ObservableCollection,与 VS.NET 并行运行您的应用程序,单击排序按钮(或其他),然后单击 VS.NET 中的 Break All 按钮并查看堆栈跟踪。点击 Continue 并立即再次点击 Break All,然后再次查看堆栈跟踪。重复多次。这将使您对花费所有额外时间的原因有一个很好的了解。

  • 如果,正如我所怀疑的,问题是 UserControls 创建和绑定(bind)速度慢,您会发现: 每次更改列表时都会出现问题,并且在更改过滤器时也会发生问题,当您将 UserControls 替换为 <CheckBox/> 时,事情会加快速度。 ,你的构造函数每个项目只会被调用一次,调用之间的时间会很长。

    请注意,我并不是说 UserControls 的构造函数很慢 - 可能是 UserControl 在数据绑定(bind)时实例化了许多子对象,或者它包含缓慢或复杂的对象,子对象加载一个文件,或许多其他可能的原因。底线是在对象上实例化 DataTemplate 并将其添加到可视化树中的速度很慢。堆栈跟踪应该让您知道在哪里查看。

    如果结果是其他问题或者您无法弄清楚,只需更新您的问题以提供有关上述测试所揭示内容的更多信息,我们会尽力帮助您。

    关于wpf - 为什么 ListCollectionView.CustomSort 这么慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2028835/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com