Search code examples
wpfrouted-events

Get TreeViewItem datacontext from root container


I have a Window with two use controls. One encapsulates a TreeView control and another is marely a string representation of a selected TreeViewItems details.

TreeView controls is already self sufficient - it will populate itself with content items. Each TreeViewItem has a datacontext.

Here is what I need to happen:

  1. Whenever a user clicks an item, it generates a Selected routed event that is being caught at the root container of my window.
  2. I need the event handler, that handles Selected routed event to be able to get some data (a property value) from the selected TreeViewItem's data context.
  3. Based on this value, my event handler will create a DetailsView control and will populate it with data.

Is my approach correct, in respect to handling the Selected events? How can I get the property value from my selected items data context?

Thank you.


Solution

  • Binding a property to the SelectedItem of TreeView can fix your issue. The code below express what I'm considering. For the two UC you have, you can expose one property for the SelectedItem.

    XAML:

    <TreeView x:Name="Tree1">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Items}">
                <TextBlock Text="{Binding Name}" />
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>
    <TextBlock Text="{Binding ElementName=Tree1,Path=SelectedItem.Name}" />
    

    Entity Of Item

    public class Item
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private string name;
        private Collection<Item> items;
    
        public Collection<Item> Items { get { return items; } }
    
        public Item()
        {
            items = new Collection<Item>();
        }
    
        public string Name
        {
            get { return name; }
            set { name = value; OnPropertyChanged("Name"); }
        }
    
        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    

    Binding Source

    Item item = new Item { Name = "A" };
    item.Items.Add(new Item { Name = "A_1" });
    item.Items.Add(new Item { Name = "A_2" });
    item.Items.Add(new Item { Name = "A_3" });
    Tree1.ItemsSource = new Collection<Item>() { item };