You can do it at least two ways. First way is to redefine whole treeview style. You can find some examples how to do it here (The example doesn't solve your problem, but you can get the general idea). Downside of this solution is that code is pretty big and it will look the same on every system, like Windows XP of Windows 10, because in normal situation every system uses its own style.
I prefer to solve such a problems another way. I make changes from C# code. For example, in your case, you can see the structure of treeview in Visual Studio Xaml visualiser:
Every treeview item contains a ToggleButton - to expand and collapse on the first row of the grid. Next goes a border which contains TextBlock with the content of the item (In your case it can be another control from your datatemplate, I took textblock for the example). It placed on the same first row. In the second row of the grid there is ItemsPresenter containing child elements.
So, the goal is to add one more row two the grid and put a textblock there.
First, add ItemContainerStyle to the treeview and set event handler there:
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<EventSetter Event="Loaded" Handler="Item_Loaded"/>
</Style>
</TreeView.ItemContainerStyle>
And then in the code behind:
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);
}
It is not the ideal solution, Xaml can be different on different systems, so this function can be slightly different. I checked it only on windows 10.
The FindVisualChild function is like this:
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;
}