英文:
Improve WPF / telerik (Rad)TreeListView bad scrolling performance
问题
我在我的.NET 6 WPF应用程序中使用了一个telerik的RadTreeListView,在滚动过程中性能非常差。
使用滚轮时,更新可能需要2秒,快速拖动垂直滚动条会导致小于等于5秒的延迟。
我大约有350行数据,这些数据组织在单个顶级元素下。视图有5个手动定义的列。
我对性能进行了分析,发现几乎所有UI线程上花费的CPU时间都用于布局:

我尝试启用了虚拟化功能,使用了属性EnableRowVirtualization,EnableColumnGroupsVirtualization,EnableColumnVirtualization。
我可以采取哪些步骤来提高滚动性能?
英文:
I use a telerik RadTreeListView in my .NET 6 WPF application and experience very bad performance during scrolling.
Updates when using the scroll wheel can take 2 seconds and dragging the vertical scroll bar quickly results in lag spikes of <=5 seconds.
I have about 350 rows which are organized under a single top-level element. The view has 5 manually defined columns.
I profiled the performance and saw that virtually all the CPU time spent on the UI thread is used for layouting:

I tried enabling the virtualizing functionality by using the attributes EnableRowVirtualization, EnableColumnGroupsVirtualization, EnableColumnVirtualization.
What steps can I take to improve my scroll performance?
Edit: Here is the XAML of an example project that illustrates my problem.
<telerik:RadBusyIndicator Grid.Column="1" Grid.Row="1"
BusyContent="{Binding BusyReason}" IsBusy="{Binding BusyReason, Converter={StaticResource stringEmptyConverter}}" >
<telerik:RadTreeListView x:Name="treeView" ItemsSource="{Binding Pages, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"
AutoGenerateColumns="False" AutoExpandItems="True"
SelectedItem="{Binding SelectedPage}"
PreviewMouseRightButtonDown="RadTreeListView_PreviewMouseRightButtonDown" IsDragDropEnabled="False"
PreparedCellForEdit="treeView_PreparedCellForEdit"
BeginningEdit="treeView_BeginningEdit"
CanUserDeleteRows="False"
EnableRowVirtualization="True"
EnableColumnGroupsVirtualization="False"
EnableColumnVirtualization="False"
GroupRenderMode="Flat"
IsPropertyChangedAggregationEnabled="False"
>
<telerik:RadTreeListView.ChildTableDefinitions>
<telerik:TreeListViewTableDefinition ItemsSource="{Binding ChildElements, Mode=TwoWay}"/>
</telerik:RadTreeListView.ChildTableDefinitions>
<telerik:RadTreeListView.Columns>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Name, TargetNullValue=''}" Header="ID Name"
Width="Auto" IsSortable="False" IsFilterable="False"/>
<telerik:GridViewComboBoxColumn Header="ID" DataMemberBinding="{Binding Id, Mode=TwoWay}"
IsSortable="False" IsFilterable="False"
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type telerik:RadTreeListView}}, Path=DataContext.Ids}"
Width="100"
x:Name="columnWarnId"
IsLightweightModeEnabled="True"
EmptyText="not set"
>
<telerik:GridViewComboBoxColumn.EditorStyle>
<Style TargetType="telerik:RadComboBox" BasedOn="{StaticResource RadComboBoxStyle}">
<Setter Property="OpenDropDownOnFocus" Value="True"/>
</Style>
</telerik:GridViewComboBoxColumn.EditorStyle>
<telerik:GridViewComboBoxColumn.ItemTemplate>
<DataTemplate DataType="{x:Type dt:DataObject}">
<telerik:Label Content="{Binding IdName}"/>
</DataTemplate>
</telerik:GridViewComboBoxColumn.ItemTemplate>
</telerik:GridViewComboBoxColumn>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Ca, TargetNullValue=''}" Header="Foobar"
IsFilterable="False"
Width="65"
x:Name="columnCa"
/>
<telerik:GridViewDataColumn DataMemberBinding="{Binding HasChanged, TargetNullValue=''}" Header="*"
IsFilterable="False"
IsReadOnly="True">
<telerik:GridViewDataColumn.CellTemplate>
<DataTemplate>
<TextBlock Visibility="{Binding HasChanged, Converter={helpers:BooleanToVisibilityConverter}}" Text="*"/>
</DataTemplate>
</telerik:GridViewDataColumn.CellTemplate>
</telerik:GridViewDataColumn>
<telerik:GridViewDataColumn DataMemberBinding="{Binding WarningsPresent, TargetNullValue=''}" Header="Warning"
IsFilterable="False"
IsReadOnly="True">
<telerik:GridViewDataColumn.CellTemplate>
<DataTemplate>
<Image HorizontalAlignment="Center" Visibility="{Binding WarningsPresent, Converter={helpers:BooleanToVisibilityConverter}}" Source="pack://application:,,,/Resources/Images/icons8-fehler-48.png"
Stretch="Uniform"
MaxHeight="24"/>
</DataTemplate>
</telerik:GridViewDataColumn.CellTemplate>
</telerik:GridViewDataColumn>
</telerik:RadTreeListView.Columns>
</telerik:RadTreeListView>
</telerik:RadBusyIndicator>
答案1
得分: 0
Telerik支持提供了反馈。
性能问题源于GridViewComboBoxColumn,在我的情况下,显示大约200个条目(每行都相同)。
这是一个已知问题,自2015年以来telerik并不认为它是一个bug。
根本原因是底层的RadComboBox即使没有扩展也会评估其内容。当我从我的RadTreeView中移除GridViewComboBoxColumn时,在_Debug_模式下性能提高到可接受水平,_Release_模式下性能良好。
上面链接的支持页面建议将ComboBox的项目重写为字典,以提高telerik内部的性能。
英文:
The telerik Support offered feedback.
The performance problem stems from the GridViewComboBoxColumn that - in my case - displays ~200 entries (the same for each row).
It's a known issue that is not considered a bug by telerik since 2015.
The root cause is that the underlying RadComboBox evaluates its contents even if it's not extended. When I removed the GridViewComboBoxColumn from my RadTreeView, performance jumped to acceptable levels in Debug mode and good performance in Release mode.
The support page linked above suggests rewriting the collection for the ComboBox' items to a dictionary so that telerik-internal performance is improved.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论