WPF DataBound treeview expand / collapse - wpf

I'm just trying to find a way to control the expand / collapse of the TreeView nodes through the object they're bound to. The object has an IsExpanded property, and I want to use that to show the TreeView node itself expanded or collapsed based on that property.
Here's my code:
C#:
public partial class Window2 : Window
{
public Window2()
{
InitializeComponent();
this.DataContext = new List<Parent>() { Base.GetParent("Parent 1"), Base.GetParent("Parent 2") };
}
}
public class Base
{
public string Name { get; set; }
public bool IsExpanded { get; set; }
public static Parent GetParent(string name)
{
Parent p = new Parent() { Name = name };
p.Children.Add(new Child() { Name = "Child 1", GrandChildren = new ObservableCollection<GrandChild>() { new GrandChild() { Name = "Grandchild 1" } } });
p.Children.Add(new Child() { Name = "Child 2", GrandChildren = new ObservableCollection<GrandChild>() { new GrandChild() { Name = "Grandchild 1" } } });
p.Children.Add(new Child() { Name = "Child 3", GrandChildren = new ObservableCollection<GrandChild>() { new GrandChild() { Name = "Grandchild 1" } } });
return p;
}
}
public class Parent : Base
{
public ObservableCollection<Child> Children { get; set; }
public Parent()
{
this.Children = new ObservableCollection<Child>();
}
}
public class Child : Base
{
public ObservableCollection<GrandChild> GrandChildren { get; set; }
public Child()
{
this.GrandChildren = new ObservableCollection<GrandChild>();
}
}
public class GrandChild : Base
{
}
XAML:
<Window x:Class="HeterogeneousExperimentExplorer.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:HeterogeneousTree"
Title="Window2" Height="300" Width="300">
<Window.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:Parent}" ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}" />
<HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:Parent}" ItemsSource="{Binding GrandChildren}">
<TextBlock Text="{Binding Name}" />
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</Window.Resources>
<Grid>
<TreeView ItemsSource="{Binding}" />
</Grid>
</Window>

Came up with solution:
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsNodeExpanded}"/>
</Style>
So the style gets the object bound to the TreeViewItem and looks at its IsNodeExpanded attribute and it assigns that value to the TreeViewItem.IsExpanded property. If you add Mode=TwoWay, they'll notify each other (TreeViewItem will tell the object when it has been expanded).

Related

WPF TreeView with multiple DataTypes and possibly leafs on each node

I face a problem using WPF.
Let's take those examples classes which reproduce what I'm trying to do :
public class Element
{
public string Name { get; set; }
public IList<Element> SubElements { get; set; } = new List<Element>();
public IList<Value> Values { get; set; } = new List<Value>();
}
public class Value
{
public string Name { get; set; }
}
Each Element instance can have (or not) its own list of Values.
For example i'd like to display the following root on my TreeView :
Element root = new Element() { Name = "Root" };
Element subElement1 = new Element() { Name = "SubElement1" };
Element subElement1_1 = new Element() { Name = "SubElement1_1" };
Value valueSubElement1_1 = new Value() { Name = "SubElement1_1_Value" };
subElement1_1.Values.Add(valueSubElement1_1);
subElement1.SubElements.Add(subElement1_1);
root.SubElements.Add(subElement1);
Element subElement2 = new Element() { Name = "SubElement2" };
Value valueSubElement2 = new Value() { Name = "SubElement2_Value" };
subElement2.Values.Add(valueSubElement2);
root.SubElements.Add(subElement2);
How could I do that ? I struggle to find a correct answer to this.
Here is the xaml i started with :
<TreeView x:Name="TreeView" Grid.Row="0" ItemsSource="{Binding TreeViewElements, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}}}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:Element}" ItemsSource="{Binding SubElements}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type local:Value}">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</TreeView.Resources>
</TreeView>
With TreeViewElements :
public IList<Element> TreeViewElements { get; set; } = new List<Element>();
to which I added my root object.
With that I can perfectly display all of my Element objects, but not the Values.
And I get why ; when I specified the ItemsSource I gave an item of type Element, so it'll never see the values inside.
So how could I do that ?
Thanks in advance for your answers and have a good day.
You can define as many templates as you like based on type but there can only be the one itemssource to a treeviewitem.
You could alter your Element or create a new ElementViewModel which had a list
public class Element
{
public string Name { get; set; }
public IList<object> Children { get; set; } = new List<object>();
}
You could then add an Element or Value to children.
Having said that.
Element has Name and SubElements, Value just has Name. It looks like you could just use an Element with an empty collection of SubElements instead of Value.
Just have
public class Element
{
public string Name { get; set; }
public IList<Element> SubElements { get; set; } = new List<Element>();
}
You would have to add another ItemsControl to the template to displays an additional collection on the same tree level.
Alternatively, if you want to display multiple types in the same tree then you would have to change your data structure with the goal to add all child items to the same source collection.
Solution 1
In order to be able hide the nested ToggleButton (that is used as the node's expander in this example) using a Trigger (in case the Element.Values source collection is empty) you could introduce a HasValues property:
Element.cs
public class Element
{
public string Name { get; set; }
public IList<Element> SubElements { get; set; } = new List<Element>();
public IList<Value> Values { get; set; } = new List<Value>();
public bool HasValues => this.Values.Count > 0;
}
The following modified TreeView example uses ToggleButton to toggle the Visibility of the nested ItemsControl.
Optionally, to match the look of the expander with the expander of the TreeView, you can extract the TreeView style using Visual Studio you will also get the ToggleButton style that the TreeView uses to style the tree node's expander. You can then set this Style to the below ToggleButton that toggles the visibility of the nested ItemsControl. In this case you would have to remove the ToggleButton.Content value that is currently set.
<TreeView>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:Element}"
ItemsSource="{Binding SubElements}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<ToggleButton x:Name="Expander"
Grid.Row="0"
Grid.Column="0"
Content=">"
Margin="-24,0,0,0"
Visibility="Collapsed"
HorizontalAlignment="Left" />
<TextBlock x:Name="Header"
Grid.Row="0"
Grid.Column="1"
Text="{Binding Name}" />
<ItemsControl x:Name="ValueHost"
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Visibility="Collapsed"
ItemsSource="{Binding Values}" />
</Grid>
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding HasValues}"
Value="True">
<Setter TargetName="Expander"
Property="Visibility"
Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=Expander, Path=IsChecked}"
Value="True">
<Setter TargetName="ValueHost"
Property="Visibility"
Value="Visible" />
</DataTrigger>
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type local:Value}">
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</TreeView.Resources>
</TreeView>
Solution 2
In your case you could introduce a common interface that declares the Name property. You can use this interface or the least common type (object) as the type of the container collection:
INode.cs
interface INode : INotifyPropertyChanged
{
string Name { get; set; }
}
Element.cs
// TODO::Implement INotifyPropertyChnaged
class Element : INode
{
public IList<INode> ChildNodes { get; set; }
public string Name { get; set; }
}
Value.cs
// TODO::Implement INotifyPropertyChnaged
class Element : INode
{
public string Name { get; set; }
}
Example
Element root = new Element() { Name = "Root" };
Element subElement1 = new Element() { Name = "SubElement1" };
Element subElement1_1 = new Element() { Name = "SubElement1_1" };
Value valueSubElement1_1 = new Value() { Name = "SubElement1_1_Value" };
subElement1_1.ChildNodes.Add(valueSubElement1_1); subElement1.ChildNodes.Add(subElement1_1);
root.ChildNodes.Add(subElement1);
Element subElement2 = new Element() { Name = "SubElement2" };
Value valueSubElement2 = new Value() { Name = "SubElement2_Value" };
subElement2.ChildNodes.Add(valueSubElement2);
root.ChildNodes.Add(subElement2);
<TreeView>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:Element}"
ItemsSource="{Binding ChildNodes}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type local:Value}">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</TreeView.Resources>
</TreeView>

WPF ListBox selected item, stays selected while loosing focus

I have a parent ListBox which is made of two listboxes, and a child listbox, so 3 listboxes in total. The Item source for the first two are just two separate collections, these collections contain inner collection which then become an item source for the third listbox. If I select second item then the child listbox is populated again, if I go to the second parent listbox and chose something then the child listbox is populated. The problem is that if at this point I go back to the first listbox, and try to select an item that was previously selected, nothing happens, while im expecting it to populate the child listbox again.
Hopefully this makes sense, here is the XAML:
<Window x:Class="ExampleForStackOverFlow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="350" Height="350">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel>
<TextBlock Text="Parents" FontSize="20" FontWeight="Bold" Background="LightBlue"/>
<TextBlock Text="First Listbox" FontSize="16" FontWeight="Bold" Background="LightBlue"/>
<ListBox ItemsSource="{Binding Parents1}" SelectedItem="{Binding SelectedParent}" BorderThickness="0">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBlock Text="Second Listbox" FontSize="16" FontWeight="Bold" Background="LightBlue"/>
<ListBox ItemsSource="{Binding Parents2}" SelectedItem="{Binding SelectedParent2}" BorderThickness="0">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
<StackPanel Grid.Column="1">
<TextBlock Text="Children" FontSize="16" FontWeight="Bold" Background="LightBlue"/>
<ListBox ItemsSource="{Binding Children}" BorderThickness="0">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Grid>
This is the ViewModel
using System.Collections.ObjectModel;
namespace ExampleForStackOverFlow
{
public class MainWindowViewModel : NotifyPropertyChanged
{
public MainWindowViewModel()
{
Parents1 = new ObservableCollection<Parent>();
Parents2 = new ObservableCollection<Parent>();
foreach (var parent in ParentCollection.GetParents())
{
if (parent.Name == "Parent 1" || parent.Name == "Parent 2")
{
Parents1.Add(parent);
}
else
{
Parents2.Add(parent);
}
}
Children = new ObservableCollection<Child>();
}
public ObservableCollection<Parent> Parents1 { get; set; }
public ObservableCollection<Parent> Parents2 { get; set; }
private ObservableCollection<Child> children;
public ObservableCollection<Child> Children
{
get { return children; }
set
{
children = value;
OnPropertyChanged("Children");
}
}
private Parent selectedParent;
public Parent SelectedParent
{
get { return selectedParent; }
set
{
selectedParent = value;
Children = SelectedParent.Children;
OnPropertyChanged("SelectedParent");
}
}
private Parent selectedParent2;
public Parent SelectedParent2
{
get { return selectedParent2; }
set
{
selectedParent2 = value;
Children = SelectedParent2.Children;
OnPropertyChanged("SelectedParent2");
}
}
}
public class Parent : NotifyPropertyChanged
{
private string name;
public string Name
{
get { return name; }
set
{
name = value;
OnPropertyChanged("Name");
}
}
private ObservableCollection<Child> childres;
public ObservableCollection<Child> Children
{
get { return childres; }
set
{
childres = value;
OnPropertyChanged("Children");
}
}
}
public class Child : NotifyPropertyChanged
{
private string name;
public string Name
{
get { return name; }
set
{
name = value;
OnPropertyChanged("Name");
}
}
}
}
The value for selected did not change so it is not going to fire the set
If you set it to null then a re-select will be a new value
private Parent selectedParent;
public Parent SelectedParent
{
get { return selectedParent; }
set
{
selectedParent2 = null;
selectedParent = value;
Children = SelectedParent.Children;
OnPropertyChanged("SelectedParent");
OnPropertyChanged("SelectedParent2"); // you may not need this
}
}
private Parent selectedParent2;
public Parent SelectedParent2
{
get { return selectedParent2; }
set
{
selectedParent = null;
selectedParent2 = value;
Children = SelectedParent2.Children;
OnPropertyChanged("SelectedParent"); // you may not need this
OnPropertyChanged("SelectedParent2");
}
}

Disable treeview root node when using hierarchicaldatatemplate

im using WPF/MVVM to fool around with a treeview control
<TreeView HorizontalAlignment="Left"
Height="319"
VerticalAlignment="Top"
Width="517"
ItemsSource="{Binding Tree}"
>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<Button Width="100" Height="20" IsEnabled="{Binding IsEnabled}" Content="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
And this is my viewmodel with the node class
public partial class MainWindow : Window
{
class TreeNode
{
public string Name { get; set; }
public bool IsEnabled { get; set; }
public List<TreeNode> Children { get; set; }
public TreeNode()
{
Children = new List<TreeNode>();
IsEnabled = true;
}
}
class ViewModel
{
public List<TreeNode> Tree { get; private set; }
public ViewModel()
{
Tree = new List<TreeNode>();
}
}
public MainWindow()
{
InitializeComponent();
var viewModel = new ViewModel
{
Tree =
{
new TreeNode
{
Name = "Root 1",
IsEnabled = false,
Children = {
new TreeNode { Name = "Child 1" },
new TreeNode { Name = "Child 2" },
new TreeNode { Name = "Child 3",
Children =
{
new TreeNode { Name = "Child 3-1" },
new TreeNode { Name = "Child 3-2" },
new TreeNode { Name = "Child 3-3" },
}
},
}
}
}
};
DataContext = viewModel;
}
}
As you can see, i bind the property "IsEnabled" to the button, this is all good, but i actually want to bind the "IsEnabled" property to the actual root node element, not a object within the node.
What would i need to do to disable the entire root node based on this property value?
To do this, you actually need to affect the ItemContainerStyle for the TreeView. This sets the style for the ItemContainer (TreeViewItem) that is generated for each node of the Tree.
<TreeView HorizontalAlignment="Left" Height="319" VerticalAlignment="Top" Width="517" ItemsSource="{Binding Tree}">
<TreeView.ItemTemplate>
<!-- Leave this the same, except for the IsEnabled binding on the button -->
</TreeView.ItemTemplate>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsEnabled" Value="{Binding IsEnabled}"/>
</Style>
</TreeView.ItemContainerStyle>
</TreeView>

DataTemplate disappears when moving items in ObservableCollection

I have a CellTemplate for a column in a ListView. The CellTemplate contains a ComboBox which has an ItemTemplate. Both ItemsSource and SelectedItem is bound to another ViewModel.
The ListView is bound to an ObservableCollection on a ViewModel. Above the ListView there is a toolbar with the buttons to move the selected item up and down. I buttons a bound to and ICommand which will make a Move on the ObservableCollection.
The view is updated fine, but the selected item in the ComboBox is not using the DataTemplate and is just showing the type name.
I found out that everything is working fine if IsEditable = false, but I need this to be true.
I have created a small project that verifies the problem. Perhaps this is an issue in WPF.
Here is XAML:
<Window x:Class="WpfApplication3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:WpfApplication3="clr-namespace:WpfApplication3"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<DataTemplate DataType="{x:Type WpfApplication3:Item}">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
<DataTemplate x:Key="cellTemplate">
<ComboBox ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}" Width="100" IsEditable="true" TextSearch.TextPath="Name"/>
</DataTemplate>
</Window.Resources>
<Grid>
<StackPanel>
<ToolBar>
<Button Content="Add" Command="{Binding AddItemCommand}"/>
<Button Content="Up" Command="{Binding MoveItemUpCommand}" CommandParameter="{Binding ElementName=listView, Path=SelectedItem}"/>
<Button Content="Down" Command="{Binding MoveItemDownCommand}" CommandParameter="{Binding ElementName=listView, Path=SelectedItem}"/>
</ToolBar>
<ListView x:Name="listView" ItemsSource="{Binding Collection}">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" CellTemplate="{StaticResource cellTemplate}"/>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
</Grid>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
}
public class ViewModel
{
public ICommand AddItemCommand { get; private set; }
public ICommand MoveItemUpCommand { get; private set; }
public ICommand MoveItemDownCommand { get; private set; }
public ObservableCollection<Row> Collection { get; set; }
public ViewModel()
{
Collection = new ObservableCollection<Row>();
AddItemCommand = new RelayCommand(AddItem);
MoveItemUpCommand = new RelayCommand<Row>(MoveItemUp, CanMoveItemUp);
MoveItemDownCommand = new RelayCommand<Row>(MoveItemDown, CanMoveItemDown);
}
private bool CanMoveItemDown(Row arg)
{
if (arg == null)
return false;
return Collection.Last() != arg;
}
private void MoveItemDown(Row obj)
{
var index = Collection.IndexOf(obj);
Collection.Move(index, index + 1);
}
private bool CanMoveItemUp(Row arg)
{
if (arg == null)
return false;
return Collection.First() != arg;
}
private void MoveItemUp(Row row)
{
var index = Collection.IndexOf(row);
Collection.Move(index, index - 1);
}
private void AddItem()
{
Collection.Add(new Row());
}
}
public class Row
{
public Row()
{
Items = new List<Item> { new Item { Name = "Test1" }, new Item { Name = "Test2" } };
}
public List<Item> Items { get; set; }
public Item SelectedItem { get; set; }
}
public class Item
{
public string Name { get; set; }
public int Order { get; set; }
}

DataTemplate inside HierarchicalDataTemplate

I needed to build a custom treeview as a user control. I called it for the sake of the example TreeViewEx :
<UserControl x:Class="WpfApplication4.TreeViewEx"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="root">
<Grid>
<TreeView ItemsSource="{Binding Path=ItemsSource, ElementName=root}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Node : "/>
<ContentControl Content="{Binding Path=AdditionalContent, ElementName=root}"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
</UserControl>
The idea is to have a fixed part of the content of the ItemTemplate and a customizable part of it.
Of course, I created two dependency properties on the TreeViewEx class :
public partial class TreeViewEx
{
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(
"ItemsSource", typeof(IEnumerable), typeof(TreeViewEx));
public IEnumerable ItemsSource
{
get { return (IEnumerable)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
public static readonly DependencyProperty AdditionalContentProperty = DependencyProperty.Register(
"AdditionalContent", typeof(object), typeof(TreeViewEx));
public object AdditionalContent
{
get { return GetValue(AdditionalContentProperty); }
set { SetValue(AdditionalContentProperty, value); }
}
public TreeViewEx()
{
InitializeComponent();
}
}
Having a simple node class like so :
public class Node
{
public string Name { get; set; }
public int Size { get; set; }
public IEnumerable<Node> Children { get; set; }
}
I would feed the treeview. I place an instance of TreeViewEx on the MainWindow of a WPF test project :
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:local="clr-namespace:WpfApplication4">
<Grid>
<local:TreeViewEx x:Name="tree">
<local:TreeViewEx.AdditionalContent>
<TextBlock Text="{Binding Name}"/>
</local:TreeViewEx.AdditionalContent>
</local:TreeViewEx>
</Grid>
</Window>
And finally feed it :
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
var dummyData = new ObservableCollection<Node>
{
new Node
{
Name = "Root",
Size = 3,
Children = new ObservableCollection<Node>
{
new Node{
Name="Child1",
Size=2,
Children = new ObservableCollection<Node>{
new Node{
Name = "Subchild",
Size = 1
}
}
}
}
}
};
tree.ItemsSource = dummyData;
}
}
However it doesn't work as expected namely at first the ContentControl has the data but as I expand the nodes it does not display the ContentControl's content.
I don't really get it.. I should use a DataTemplate or something else?
The problem is that you're setting the content to an instance of a control, and that control can only have one parent. When you expand the tree and it adds it to the second node, it removes it from the first one.
As you suspected, you want to supply a DataTemplate to TreeViewEx instead of a control. You can use a ContentPresenter to instantiate the template at each level of the tree:
Replace the AdditionalContentProperty with:
public static readonly DependencyProperty AdditionalContentTemplateProperty = DependencyProperty.Register(
"AdditionalContentTemplate", typeof(DataTemplate), typeof(TreeViewEx));
public DataTemplate AdditionalContentTemplate
{
get { return (DataTemplate)GetValue(AdditionalContentTemplateProperty); }
set { SetValue(AdditionalContentTemplateProperty, value); }
}
change the HierarchicalDataTemplate in your UserControl's XAML to:
<StackPanel Orientation="Horizontal">
<TextBlock Text="Node : "/>
<ContentPresenter ContentTemplate="{Binding Path=AdditionalContentTemplate, ElementName=root}"/>
</StackPanel>
and change MainWindow to:
<local:TreeViewEx x:Name="tree">
<local:TreeViewEx.AdditionalContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</local:TreeViewEx.AdditionalContentTemplate>
</local:TreeViewEx>

Resources