英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论