如果我理解正确的话,您希望显示每个 node 数据的附加信息.
For this purpose, you should override the default ControlTeplate
of the TreeViewItem
. This way you can inject a second content host below the items host (ItemsPresenter
).
If you introduce an attached property to hold a DataTemplate
that describes the additional content you can avoid to subclass TreeViewItem
. This attached property can be defined on any suitable type. This example chooses the MainWindow
.
为了避免内存泄漏,绑定源必须始终实现INotifyPropertyChanged
,或者最好将属性实现为依赖项属性.即使财产价值不会改变.
The following example shows a fragment of the extracted TreeViewItem
default Style
. It misses other referenced resources in order to compact the example.
You can extract the complete Style using the XAML designer and then paste the Style
for the TreeViewItem
from below to replace the extracted Style
of the TreeViewItem
.
I have annotated the modified parts to help spotting the required modifications.
MainWindow.xanl.cs个
partial class MainWindow : Window
{
public static DataTemplate GetExtendedContentItemTemplate(DependencyObject attachingElement)
=> (DataTemplate)attachingElement.GetValue(ExtendedContentItemTemplateProperty);
public static void SetExtendedContentItemTemplate(DependencyObject attachingElement, DataTemplate value)
=> attachingElement.SetValue(ExtendedContentItemTemplateProperty, value);
public static readonly DependencyProperty ExtendedContentItemTemplateProperty = DependencyProperty.RegisterAttached(
"ExtendedContentItemTemplate",
typeof(DataTemplate),
typeof(MainWindow),
new PropertyMetadata(default));
}
MainWindow.xaml个
<Window>
<Window.Resources>
<!-- The example DataTemplate for the extended content -->
<DataTemplate x:Key="ExtendedDataContentTemplate"
DataType="NestedContainer">
<StackPanel>
<TextBlock Text="{Binding ActionData}" />
<TextBlock Text="{Binding Modifier}" />
</StackPanel>
</DataTemplate>
<!--
The fragment of the complete TreeViewItem style.
The first setter that sets the attached 'ExtendedContentItemTemplate' property
and the ControlTemplate that extends the layout to add the ContentControl
for the additional content are of special interest here.
-->
<Style TargetType="{x:Type TreeViewItem}">
<!-- Assign the DataTemplate for the extended content to the attached property -->
<Setter Property="local:MainWindow.ExtendedContentItemTemplate"
Value="{StaticResource ExtendedDataContentTemplate}" />
<Setter Property="Background"
Value="Transparent" />
<Setter Property="HorizontalContentAlignment"
Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="VerticalContentAlignment"
Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="Padding"
Value="1,0,0,0" />
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="FocusVisualStyle"
Value="{StaticResource TreeViewItemFocusVisual}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="19"
Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <!-- Default header row -->
<RowDefinition /> <!-- Default child items row -->
<RowDefinition Height="Auto" /> <!-- New extra content row -->
</Grid.RowDefinitions>
<ToggleButton x:Name="Expander"
ClickMode="Press"
IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource Mode=TemplatedParent}}"
Style="{StaticResource ExpandCollapseToggleStyle}" />
<Border x:Name="Bd"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Grid.Column="1"
Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="true">
<ContentPresenter x:Name="PART_Header"
ContentSource="Header"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
<ItemsPresenter x:Name="ItemsHost"
Grid.Column="1"
Grid.ColumnSpan="2"
Grid.Row="1" />
<!--
The host for the extra content below the child items.
For this purpose we have to introduce a third row to the Grid.
The Content is the data item itself (in this case 'NestedContainer').
The ContentTemplate binds to the attached property ExtendedContentItemTemplate
that is set on the TreeViewItem via the current Style (see style setter above).
-->
<ContentControl Grid.Row="2"
Grid.Column="1"
Content="{TemplateBinding DataContext}"
ContentTemplate="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:MainWindow.ExtendedContentItemTemplate)}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded"
Value="false">
<Setter Property="Visibility"
TargetName="ItemsHost"
Value="Collapsed" />
</Trigger>
<Trigger Property="HasItems"
Value="false">
<Setter Property="Visibility"
TargetName="Expander"
Value="Hidden" />
</Trigger>
<Trigger Property="IsSelected"
Value="true">
<Setter Property="Background"
TargetName="Bd"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected"
Value="true" />
<Condition Property="IsSelectionActive"
Value="false" />
</MultiTrigger.Conditions>
<Setter Property="Background"
TargetName="Bd"
Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}" />
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}" />
</MultiTrigger>
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="VirtualizingPanel.IsVirtualizing"
Value="true">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<TreeView ItemsSource="{Binding}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="NestedContainer"
ItemsSource="{Binding ChildContainers}">
<TextBlock Text="{Binding XID}" />
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
</Window>