我制作了一个包含多列的自定义 TreeView。一切都运行良好,直到树中有很多项目。
我尝试通过这样做来启用虚拟化VirtualizingPanel.IsVirtualizing="True"
(VirtualizingStackPanel.IsVirtualizing
如果您是 < .NET 4.5 则将是),但它不仅没有加快速度,而且实际上使加载时间变得更糟。
在普通的 TreeView 上,这个属性可以解决问题,但我找不到让它在我的自定义树上工作的方法
树视图项.cs
public class TreeListViewItem : TreeViewItem
{
protected override DependencyObject GetContainerForItemOverride()
{
return new TreeListViewItem();
}
protected override bool IsItemItsOwnContainerOverride(object item)
{
return item is TreeListViewItem;
}
}
树列表视图.cs
public class TreeListView : TreeView
{
public GridViewColumnCollection Columns { get; set; }
public TreeListView()
{
Columns = new GridViewColumnCollection();
}
protected override DependencyObject GetContainerForItemOverride()
{
return new TreeListViewItem();
}
protected override bool IsItemItsOwnContainerOverride(object item)
{
return item is TreeListViewItem;
}
}
节点.cs
public class Node
{
public string Data { get; set; }
public List<Node> Children { get; set; }
public Node(string data)
{
Data = data;
Children = new List<Node>();
}
}
视图模型.cs
public class ViewModel
{
public ObservableCollection<Node> Nodes { get; private set; }
public ViewModel()
{
Nodes = new ObservableCollection<Node>();
Node parent = new Node("Parent");
for (int i = 0; i < 5000; i++)
parent.Children.Add(new Node(i.ToString()));
Nodes.Add(parent);
}
}
主窗口.xaml
<Window x:Class="WPFTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFTest"
Title="Test"
mc:Ignorable="d"
Width="200">
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<Window.Resources>
<Style TargetType="local:TreeListView">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:TreeListView">
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer VerticalScrollBarVisibility="Disabled">
<DockPanel>
<GridViewHeaderRowPresenter Columns="{Binding Path=Columns, RelativeSource={RelativeSource TemplatedParent}}"
DockPanel.Dock="Top"/>
<ScrollViewer HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto"
DockPanel.Dock="Bottom">
<ItemsPresenter/>
</ScrollViewer>
</DockPanel>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="local:TreeListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:TreeListViewItem">
<StackPanel>
<Border Name="Bd"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}">
<GridViewRowPresenter x:Name="PART_Header"
Content="{TemplateBinding Header}"
Columns="{Binding Path=Columns, RelativeSource={RelativeSource AncestorType={x:Type local:TreeListView}}}" >
</GridViewRowPresenter>
</Border>
<ItemsPresenter x:Name="ItemsHost" />
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="false">
<Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<local:TreeListView ItemsSource="{Binding Nodes}" VirtualizingPanel.IsVirtualizing="True">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}"/>
</TreeView.ItemTemplate>
<local:TreeListView.Columns>
<GridViewColumn Header="Test" Width="150">
<GridViewColumn.CellTemplate>
<DataTemplate>
<DockPanel>
<TextBlock Text="{Binding Data}"/>
</DockPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</local:TreeListView.Columns>
</local:TreeListView>
</Grid>
</Window>
我尝试将 ItemPanel 模板化VirtualizingStackPanel
,但它也没有帮助。
我去掉了扩展器部分,因为它不相关。您可以双击父节点展开树,加载子节点需要很长时间。