我有一个带有两级层次结构的TreeView。 TreeView项绑定到特定类的属性。基本上,我得到ObservableCollection列表,并将该列表分配为我的TreeView ItemsSource。最初,treeView可见性设置为Collapsed,分配ItemsSource后,TreeView可见性设置为Visible。此时应用程序会卡顿约40秒钟(基本上是加载数千个父项和每个父项5-10个子项)。
代码背后是:
我最终得到了TreeView,但问题是在填充TreeView时我的应用程序会冻结..!! 有人知道解决方法吗?我已经有了滚动条,这会对虚拟化造成问题吗?
PS:生成的TreeView看起来像这样,但有数千个类似的节点
更新:
我正在阅读VirtualizingStackPanel,其中提到:“仅当面板中包含的项控件创建自己的项容器时,堆栈面板中的虚拟化才会发生。您可以通过使用数据绑定来确保发生这种情况。在创建并添加到项控件的项容器的情况下,VirtualizingStackPanel与StackPanel相比不会提供任何性能优势。”
有人能建议我是否应该遵循上述方法吗?我非常确定我在错误的方向上...
代码背后是:
PopulateTreeView()
{
// ocListToDisplay is my ObservableCollection
tvES.ItemsSource = ocListToDisplay;
//App Freezes at this bit when making the tvES Visible from Collapsed
tvES.Visibility = System.Windows.Visibility.Visible;
}
我的XAML代码如下:
<ScrollViewer Name="scContainer" VerticalAlignment="Stretch"
HorizontalAlignment="Stretch">
<StackPanel>
<StackPanel.Resources>
<exportImport:TreeViewDashboard x:Key="dataItems"/>
<HierarchicalDataTemplate DataType="{x:Type exportImport:TreeViewDashboard}"
ItemsSource="{Binding Path=Components}">
<Grid Margin="2" >
<Grid.ColumnDefinitions>
<ColumnDefinition ></ColumnDefinition>
<ColumnDefinition ></ColumnDefinition>
<ColumnDefinition ></ColumnDefinition>
</Grid.ColumnDefinitions>
<CheckBox Name="checkbx" Grid.Column="0" Margin="2"
Tag="{Binding Path=Tag}"
Checked="OnCheck" Unchecked="OnUnCheck"></CheckBox>
<Image Margin="2" Grid.Column="1" Source="{Binding Path=ImageUrl}"
Height="14" Width="16" ></Image>
<TextBlock Margin="2" Grid.Column="2" Text="{Binding Path=Name}"
FontWeight="Bold" />
</Grid>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<Grid Margin="2" >
<Grid.ColumnDefinitions>
<ColumnDefinition ></ColumnDefinition>
<ColumnDefinition ></ColumnDefinition>
<ColumnDefinition ></ColumnDefinition>
</Grid.ColumnDefinitions>
<CheckBox Name="checkbx" Grid.Column="0" Margin="2"
Tag="{Binding Path=Tag}"
Checked="OnCheck" Unchecked="OnUnCheck"/>
<Image Margin="2" Grid.Column="1"
Source="{Binding Path=ImageUrl}"
Height="14" Width="16" />
<TextBlock Margin="2" Grid.Column="2"
Text="{Binding Path=Name}" FontWeight="Bold" />
</Grid>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</StackPanel.Resources>
<--same result if you set IsVirtualizing to True/False App freezes for 40 sec-->
<TreeView Name="tvES" BorderThickness="0"
ItemsSource="{Binding Source={StaticResource dataItems}}"
VirtualizingStackPanel.IsVirtualizing="False"
VirtualizingStackPanel.VirtualizationMode="Recycling"
TreeViewItem.Expanded="item_Expanded"
TreeViewItem.Collapsed="item_Collapsed" >
<TreeView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</TreeView.ItemsPanel>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="False" />
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
</StackPanel>
</ScrollViewer>
我也尝试获取树形视图中的视觉元素数量。但在 IsVisualizing="True" 和 IsVisualizing="False" 的情况下,我得到了相同的 Visuals count 数量,这明显表明我做错了什么。
获取树形结构中的视觉元素数量的代码
//In my case I am passing tvES as DependencyObject
private static int GetVisualCount(DependencyObject visual)
{
int visualCount = 1;
int childCount = VisualTreeHelper.GetChildrenCount(visual);
for (int i = 0; i < childCount; i++)
{
DependencyObject childVisual = VisualTreeHelper.GetChild(visual, i);
visualCount += GetVisualCount(childVisual);
}
return visualCount;
}
我最终得到了TreeView,但问题是在填充TreeView时我的应用程序会冻结..!! 有人知道解决方法吗?我已经有了滚动条,这会对虚拟化造成问题吗?
PS:生成的TreeView看起来像这样,但有数千个类似的节点
更新:
我正在阅读VirtualizingStackPanel,其中提到:“仅当面板中包含的项控件创建自己的项容器时,堆栈面板中的虚拟化才会发生。您可以通过使用数据绑定来确保发生这种情况。在创建并添加到项控件的项容器的情况下,VirtualizingStackPanel与StackPanel相比不会提供任何性能优势。”
有人能建议我是否应该遵循上述方法吗?我非常确定我在错误的方向上...
数据
有关。您如何查询子项?它们是否是按需加载的?检索需要花费一些时间,即从数据库查询吗?如果是这样,那么这是一个数据虚拟化
问题。如果不是,则可能是UI 虚拟化
的问题。此外,请尝试删除当前实现,即GetVisualCount
。 - 123 456 789 0