WPF TreeView
| 属性名 | 属性类名 | 功能 |
| Style | Style | 定义控件自身的样式,可包含(ItemContainerStyle、Template、ItemsPanel、ItemTemplate、ItemsPresenter) |
| ItemContainerStyle | Style | 每个集合控件的Item的样式,可包含(ItemTemplate、ItemsPresenter) |
| Template | ControlTemplate | 定义控件自身的外观 |
| ItemsPanel | ItemsPanelTemplate | 定义子元素的布局容器 |
| ItemTemplate | DataTemplate | 定义每个子元素的外观 |
| HierarchicalDataTemplate | DataTemplate | 定义每个子元素的子元素的外观,对应于(ItemsPresenter) |
ItemsPanel 使用示例(适用于已经存在 TreeViewItem 的静态数据)
<Window.Resources>
<!--ItemTemplate最外层容器-->
<ItemsPanelTemplate x:Key="ItemsPanelTemplateStyle">
<StackPanel />
</ItemsPanelTemplate>
</Window.Resources>
<StackPanel>
<TreeView ItemsPanel="{StaticResource ItemsPanelTemplateStyle}">
<TreeViewItem>
<TreeViewItem.Header>
<TextBlock Text="Header is Object"/>
</TreeViewItem.Header>
</TreeViewItem>
</TreeView>
</StackPanel>
ItemsPanel 结合 ItemTemplate 使用示例(使用于 C# 动态数据)
<Window.Resources>
<!--ItemsTemplate最外层容器-->
<ItemsPanelTemplate x:Key="ItemsPanelTemplateStyle">
<StackPanel />
</ItemsPanelTemplate>
<!--ItemsTemplate每一项容器-->
<DataTemplate x:Key="DataTemplateStyle">
<TextBlock Text="{Binding Path=title}"/>
</DataTemplate>
</Window.Resources>
<StackPanel>
<TreeView x:Name="treeView"
ItemsPanel="{StaticResource ItemsPanelTemplateStyle}"
ItemTemplate="{StaticResource DataTemplateStyle}"></TreeView>
</StackPanel>
Style 使用实例,此方式可以包含(ItemsPanel、ItemTemplate)
<Window.Resources>
<Style x:Key="TreeViewStyle" TargetType="TreeView">
<!--TreeView 控件样式-->
<Setter Property="Background" Value="White"/>
<!--ItemsTemplate最外层容器-->
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<!--ItemsTemplate每一项容器-->
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding Path=title}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<TreeView x:Name="treeView" Style="{StaticResource TreeViewStyle}"></TreeView>
</StackPanel>
ItemContainerStyle 使用示例
<Window.Resources>
<Style x:Key="TreeViewItemContainerStyle" TargetType="TreeViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<!--ItemTemplate 元素-->
<ContentPresenter Grid.Row="0" ContentSource="Header"/>
<!--HierarchicalDataTemplate 元素-->
<ItemsPresenter Grid.Row="1"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<TreeView x:Name="treeView" ItemContainerStyle="{StaticResource TreeViewItemContainerStyle}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Path=nodes}">
<TextBlock Text="{Binding title}"/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</StackPanel>
C# 动态数据
public partial class WindowDemo : Window
{
public List<Demo> list;
public WindowDemo()
{
InitializeComponent();
list = new List<Demo>();
list.Add(new Demo { id = 1, pid = 0, title = "测试1" });
list.Add(new Demo { id = 2, pid = 1, title = "测试2" });
list.Add(new Demo { id = 3, pid = 1, title = "测试3" });
treeView.ItemsSource = GetTreeData(0, list);
}
/// <summary>
/// 递归生成树形数据
/// </summary>
public List<Demo> GetTreeData(int parentid, List<Demo> nodes)
{
List<Demo> mainnodes = nodes.Where(x => x.pid == parentid).ToList<Demo>();
List<Demo> othernodes = nodes.Where(x => x.pid != parentid).ToList<Demo>();
foreach (Demo grp in mainnodes)
{
grp.nodes = GetTreeData(grp.id, othernodes);
}
return mainnodes;
}
}
public class Demo
{
public int id { set; get; }
public int pid { set; get; }
public string title { set; get; }
public List<Demo> nodes { set; get; }
}

<HierarchicalDataTemplate x:Key="TreeViewItemTemplate" ItemsSource="{Binding Children,Mode=TwoWay}">
<Grid Background="Transparent">
<Grid.Resources>
<cvt:BoolToVisibility x:Key="BoolToVisibility"/>
<cvt:VisibilityToReverse x:Key="VisibilityToReverse"/>
</Grid.Resources>
<Grid Visibility="{Binding Visibility,ElementName=Grouping,Converter={StaticResource VisibilityToReverse}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Source="{Binding Icon}" VerticalAlignment="Center" HorizontalAlignment="Left" Height="50" Width="50" Margin="5"/>
<TextBlock Grid.Column="1" Text="{Binding Name}" FontSize="14" VerticalAlignment="Center" HorizontalAlignment="Left"/>
</Grid>
<Grid MinHeight="35" x:Name="Grouping" Visibility="{Binding IsGrouping,Converter={StaticResource BoolToVisibility}}">
<Border x:Name="PART_Name" VerticalAlignment="Bottom">
<TextBlock Text="{Binding Name}" Margin="5 0" VerticalAlignment="Center" HorizontalAlignment="Left"/>
</Border>
</Grid>
</Grid>
</HierarchicalDataTemplate>
<Style x:Key="TreeViewItemStyle" TargetType="{x:Type TreeViewItem}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="IsExpanded" Value="True"></Setter>
<Setter Property="Margin" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<ControlTemplate.Resources>
<cvt:IndentConverter x:Key="IndentConverter"/>
</ControlTemplate.Resources>
<Grid Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border Name="itemBackground" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}">
<Grid x:Name="ItemRoot" Margin="{Binding Converter={StaticResource IndentConverter},RelativeSource={RelativeSource TemplatedParent}}">
<ContentPresenter x:Name="PART_Header" ContentSource="Header" HorizontalAlignment="Stretch"/>
</Grid>
</Border>
<!--子节点-->
<ItemsPresenter x:Name="ItemsHost" Grid.Row="1"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" TargetName="itemBackground" Value="#C4C4C4"/>
</Trigger>
<!--包含有节点的的不被选中-->
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="HasItems" Value="True"/>
<Condition Property="IsFocused" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="Focusable" Value="False"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="HasItems" Value="False"/>
<Condition Property="IsFocused" Value="False"/>
<Condition SourceName="itemBackground" Property="IsMouseOver" Value="true"/>
</MultiTrigger.Conditions>
<Setter Property="Background" Value=" #DCDAD9" TargetName="itemBackground"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="TreeViewStyle" TargetType="{x:Type TreeView}">
<Setter Property="ScrollViewer.CanContentScroll" Value="True" />
<Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"></Setter>
<Setter Property="VirtualizingStackPanel.VirtualizationMode" Value="Recycling" />
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False" />
<Setter Property="ItemContainerStyle" Value="{StaticResource TreeViewItemStyle}"></Setter>
<Setter Property="Background" Value="#EBE9E7"/>
<Setter Property="BorderBrush" Value="#D6D6D6"/>
<Setter Property="BorderThickness" Value="0 1 1 1"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsItemsHost="True" Margin="0"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
WPF TreeView 样式:
参考:https://blog.csdn.net/qq_20758141/article/details/80345900
wpf treeview 之 整行选中 效果
https://www.cnblogs.com/aoldman/archive/2013/01/28/2879797.html
WPF的TreeView节点之间有连线
https://www.cnblogs.com/zhili/p/WPFTreeViewEx.html
WPF自定义TreeView控件样式实现QQ联系人列表效果
https://www.jb51.net/article/138521.htm
https://www.cnblogs.com/li-peng/p/3152982.html
https://www.cnblogs.com/lzjsky/p/17219184.html

wpf treeview 不需要选中
<TreeView PreviewMouseDown="TreeView_PreviewMouseDown">
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsSelected" Value="False"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="IsSelected" Value="False"/>
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
<!-- TreeView items -->
</TreeView>
C#代码:
private void TreeView_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
// 阻止鼠标点击事件,不触发项的选中
e.Handled = true;
}

浙公网安备 33010602011771号