To store an object (say, an instance of a class) in a TreeViewItem, I am currently storing the object in the TreeViewItem
's Header
and then overriding the ToString
method of that class, so that it displays the correct string header; I then cast the object back during an event.
Is this the correct way to achieve this sort of thing, or is there any better, more proper way ?
The "proper" way is to just add the object
to the TreeView
's (or TreeViewItem
's) Items
collection and use a HierarchicalDataTemplate
to control how the item is rendered:
Person.cs:
public class Person
{
private readonly ICollection<Person> _children = new ObservableCollection<Person>();
public string Name { get; set; }
public ICollection<Person> Children
{
get
{
return _children;
}
}
}
Window1.xaml.cs:
public Window1()
{
InitializeComponent();
var people = new List<Person>();
var kent = new Person() { Name = "Kent" };
kent.Children.Add(new Person() { Name = "Tempany" });
people.Add(kent);
_treeView.ItemsSource = people;
}
Window1.xaml:
<TreeView x:Name="_treeView">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:Person}" ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
The "answer" above in my view does not answer the actual question, and in fact the original question indicates that the question author already had a very efficient solution to the problem. However, the "answer" provided simply shows how to attach a sub-object to a TreeViewItem and how to subsequently render it using a custom method. While this is useful, this answer does not address the actual nature of the original question.
There are many scenarios where a TreeViewItem needs to have an external object attached which does not belong in the TreeViewItem's Items list. This facilitates access to the attached external object for application-specific purposes when the user selects the TreeViewItem from the TreeView. This concept is entirely different from the idea of adding sub-objects to a TreeViewItem.
An alternate method of solving this problem, as opposed to the solution originally implemented by the question author, is to subclass the TreeViewItem class and add custom information, such as an attached object. This principle is illustrated in the article http://msdn.microsoft.com/en-us/library/1330h6a4.aspx. After implementing this custom TreeViewItem subclass, this subclass may be added to the Items list of either a TreeView or a TreeViewItem. When the user selects the item from the TreeView, the object returned from the selection will be the custom subclass, which will contain whatever custom information the subclass has defined.
An additional advantage of using a custom TreeViewItem subclass instead of a TreeViewItem is that custom behaviors can be implemented by the subclass. For example, to display a custom tooltip when the user hovers the mouse over the item, the subclass may set a ToolTip object for itself with code like:
ToolTip tip = new ToolTip() { Content = "Tooltip display value" };
ToolTipService.SetToolTip(this, tip);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With