Search code examples
c#wpftreeview

Getting Item in hierarchical TreeView


I've got in XAML

<TreeView x:Name="FavoritesTreeView" SelectedItemChanged="FavpritesTreeView_SelectedItemChanged" PreviewMouseRightButtonUp="FavpritesTreeView_PreviewMouseRightButtonUp">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate DataType="{x:Type self:Node}" ItemsSource="{Binding Items}">
            <StackPanel Orientation="Horizontal">
                <Image Source="{Binding ImagePath}"/>
                <TextBlock x:Name="NodeTitle" Text="{Binding Title}" />
            </StackPanel>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

and in C#

private void FavpritesTreeView_PreviewMouseRightButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
    // Select TreeView Node on right click before displaying ContextMenu
    // https://stackoverflow.com/questions/592373/select-treeview-node-on-right-click-before-displaying-contextmenu

    DependencyObject obj = e.OriginalSource as DependencyObject;
    TreeViewItem treeViewItem = GetDependencyObjectFromVisualTree(obj, typeof(TreeViewItem)) as TreeViewItem;

    if (treeViewItem != null)
    {
        // do someting
    }
}

How to get NodeTitle item to change its Text, for example?

Have tried different approaches but no success. I'm expecting to get help to resolve the problem.


Solution

  • You can get it simply from Source property of MouseButtonEventArgs:

    TreeViewItem treeViewItem = (TreeViewItem)e.Source;
    

    Update

    Inside the event e.Source has TreeViewItem type: enter image description here

    And to get children of a item, you can use VisualTreeHelper class to get the children.

    For example, using answer from this SO post:

    public static T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject
    {
        if (obj != null)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                var child = VisualTreeHelper.GetChild(obj, i);
                if (child is T)
                {
                   return (T)child;
                }
    
                T childItem = FindVisualChild<T>(child);
                if (childItem != null) return childItem;
            }
        }
        return null;
    }
    

    And then use it like:

    var textBox = FindVisualChild<TextBlock>((DependencyObject)e.Source);