Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In WPF, how do I select the treeview item under my cursor on right-click?

In WPF, when I right-click on a treeview item I would like it to be Selected/Activated before showing the context menu.

This sounds pretty simple, but the inclusion of a hierachicalDataTemplate complicates things a little.

I have the following treeview:

<TreeView 
            x:Name="trv"
            ContextMenu="{StaticResource contextMenu}"
            ItemTemplate="{StaticResource treeHierarchicalDataTemplate}"
            ItemsSource="{Binding Source={StaticResource meetingItems}}" >

            <TreeView.ItemContainerStyle>
                <Style TargetType="{x:Type TreeViewItem}">
                    <EventSetter Event="TreeViewItem.PreviewMouseRightButtonDown" Handler="trv_PreviewMouseRightButtonDown"/>
                    <Setter Property="IsExpanded" Value="True"></Setter>
                </Style>
            </TreeView.ItemContainerStyle>
        </TreeView>

And here is my event handler...

private void trv_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
    TreeViewItem item = sender as TreeViewItem;
    if (item != null)
    {
        item.Focus();
        e.Handled = true;
    }

}

Note how I add an EventSetter above. This ALMOST works. But it only selects the root-level treeview node (i.e. the root parent of the node on which I right click). This may be because of my hierarchical data template? This template can contain children OF THE SAME TYPE.

Here is my hierarchical data template...

<HierarchicalDataTemplate x:Key="treeHierarchicalDataTemplate" 
                          ItemsSource="{Binding Path=ChildMeetingItems}">
    <HierarchicalDataTemplate.Triggers>
        <DataTrigger Binding="{Binding Path=Red}" Value="True">
            <Setter TargetName="img" Property="Image.Source" Value="pack://siteoforigin:,,,/images/bookRed.png"></Setter>
        </DataTrigger>
    </HierarchicalDataTemplate.Triggers>
    <StackPanel 
        x:Name="treeViewItemPanel"
        Background="Transparent"
        Orientation="Horizontal">
        <Image Width="16" Height="16"  x:Name="img" Margin="0,0,4,0" Source="pack://siteoforigin:,,,/images/bookGreen.png"></Image>
        <TextBlock Foreground="DarkGray" Text="{Binding DisplayIndex}" Margin="0,0,5,0"></TextBlock>
        <TextBlock Text="{Binding Summary}"></TextBlock>
    </StackPanel>
</HierarchicalDataTemplate>

Any idea on why only the root node instead of child nodes are selected when I right-click?

like image 864
willem Avatar asked Apr 28 '09 13:04

willem


People also ask

How do I know if TreeView node is selected?

SelectedNode; if ( tn == null ) Console. WriteLine("No tree node selected."); else Console. WriteLine("Selected tree node {0}.", tn.Name ); You can compare the returned TreeNode reference to the TreeNode you're looking for, and so check if it's currently selected.

What is TreeView item?

TreeViewItem is a HeaderedItemsControl, which means its header and collection of objects can be of any type (such as string, image, or panel). For more information, see the HeaderedItemsControl class.

What is TreeView in WPF?

A TreeViewItem control is a HeaderedItemsControl that has a Header and an Items collection. If you are defining a TreeView by using Extensible Application Markup Language (XAML), you can explicitly define the Header content of a TreeViewItem control and the items that make up its collection.


2 Answers

That's because the ItemContainerStyle is not inherited by the child nodes. You need to add the same EventSetter on the ItemContainerStyle o your HierarchicalDataTemplate.

<HierarchicalDataTemplate x:Key="treeHierarchicalDataTemplate" 
                          ItemsSource="{Binding Path=ChildMeetingItems}">
    <HierarchicalDataTemplate.Triggers>
        <DataTrigger Binding="{Binding Path=Red}" Value="True">
            <Setter TargetName="img" Property="Image.Source" Value="pack://siteoforigin:,,,/images/bookRed.png"></Setter>
        </DataTrigger>
    </HierarchicalDataTemplate.Triggers>
    <StackPanel 
        x:Name="treeViewItemPanel"
        Background="Transparent"
        Orientation="Horizontal">
        <Image Width="16" Height="16"  x:Name="img" Margin="0,0,4,0" Source="pack://siteoforigin:,,,/images/bookGreen.png"></Image>
        <TextBlock Foreground="DarkGray" Text="{Binding DisplayIndex}" Margin="0,0,5,0"></TextBlock>
        <TextBlock Text="{Binding Summary}"></TextBlock>
    </StackPanel>

<HierarchicalDataTemplate.ItemContainerStyle>
                <Style TargetType="{x:Type TreeViewItem}">
                    <EventSetter Event="TreeViewItem.PreviewMouseRightButtonDown" Handler="trv_PreviewMouseRightButtonDown"/>                    
                </Style>
            </HierarchicalDataTemplate.ItemContainerStyle>
</HierarchicalDataTemplate>
like image 109
Denis Troller Avatar answered Nov 06 '22 00:11

Denis Troller


just comment the e.Handler=true from your event handler.

like this:

private void trv_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
    TreeViewItem item = sender as TreeViewItem;
    if (item != null)
    {
        item.Focus();
       // e.Handled = true;
    }

}
like image 6
Shafi Avatar answered Nov 06 '22 01:11

Shafi