您至少可以通过两种方式做到这一点。第一种方法是重新定义整个树视图样式。您可以找到一些示例如何做到这一点here(该示例不能解决您的问题,但您可以大致了解)。这个解决方案的缺点是代码非常大,而且在每个系统上看起来都一样,比如 Windows 10 的 Windows XP,因为在正常情况下每个系统都使用自己的样式。
我更喜欢以另一种方式解决此类问题。我从 C# 代码进行更改。例如,在你的情况下,你可以在 Visual Studio Xaml 可视化器中看到 treeview 的结构:
每个树视图项都包含一个切换按钮 - 用于在网格的第一行展开和折叠。接下来是一个包含带有项目内容的 TextBlock 的边框(在您的情况下,它可以是您的数据模板中的另一个控件,我以 textblock 为例)。它放在同一个第一行。在网格的第二行有 ItemsPresenter 包含子元素。
所以,我们的目标是在网格的第二行再添加一行,并在那里放置一个文本块。
首先,将 ItemContainerStyle 添加到树视图并在那里设置事件处理程序:
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<EventSetter Event="Loaded" Handler="Item_Loaded"/>
</Style>
</TreeView.ItemContainerStyle>
然后在后面的代码中:
void Item_Loaded(object sender, RoutedEventArgs e) {
// Find the main grid of this TreeView item.
Grid grid = FindVisualChild<Grid>((DependencyObject) sender);
// Add new row, because it has only 2 and we need 3
grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
// Get the content to put into the textblock (or another control you are using in datatemplate)
string text = ((Node) grid.DataContext).Name;
// I'm using TextBlock to show example, you can use your own control
TextBlock tb = new TextBlock {
Text = text,
Foreground = new SolidColorBrush(Colors.Gray),
};
grid.Children.Add(tb);
// Visibility of our modification depends on IsExpanded and amount of child elements. If itemcontainer is collapsed or doesn't have children, we don't show this modification.
bool flag = false;
grid.SizeChanged += (sender1, e1) => {
if (flag) {
return;
}
flag = true;
tb.Visibility = grid.RowDefinitions[1].ActualHeight > 0
? Visibility.Visible
: Visibility.Collapsed;
flag = false;
};
// Set the position of the added part
tb.SetValue(Grid.RowProperty, 2);
tb.SetValue(Grid.ColumnProperty, 1);
}
这不是理想的解决方案,Xaml 在不同的系统上可能会有所不同,因此此功能可能会略有不同。我只在 Windows 10 上检查过。
FindVisualChild 函数是这样的:
static T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject {
for (int i = 0 ; i < VisualTreeHelper.GetChildrenCount(obj) ; i++) {
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child is T) {
return (T) child;
}
T childOfChild = FindVisualChild<T>(child);
if (childOfChild != null) {
return childOfChild;
}
}
return null;
}