简体   繁体   English

在WPF中,如何右键单击光标下方的树状视图?

[英]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. 在WPF中,当我右键单击树视图项目时,我希望在显示上下文菜单之前先选择/激活它。

This sounds pretty simple, but the inclusion of a hierachicalDataTemplate complicates things a little. 这听起来很简单,但是包含hierachicalDataTemplate会使事情复杂一些。

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. 请注意我如何在上面添加一个EventSetter。 This ALMOST works. 此ALMOST有效。 But it only selects the root-level treeview node (ie 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? 我为什么右键单击时为什么只选择根节点而不选择子节点?

That's because the ItemContainerStyle is not inherited by the child nodes. 这是因为ItemContainerStyle未被子节点继承。 You need to add the same EventSetter on the ItemContainerStyle o your HierarchicalDataTemplate. 您需要在HierarchicalDataTemplate的ItemContainerStyle上添加相同的EventSetter。

<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>

just comment the e.Handler=true from your event handler. 只需在事件处理程序中注释e.Handler=true

like this: 像这样:

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

}

I had the same problem - couldn't get the proper selected tree item. 我遇到了同样的问题-无法获得正确的选定树项。 And instead of using PreviewMouseRightButtonDown event I used same event of a StackPanel which also stores all needful data: 我没有使用PreviewMouseRightButtonDown事件,而是使用了StackPanel相同事件,该事件还存储了所有需要的数据:

<StackPanel DataContext="{Binding}" MouseLeftButtonDown="StackPanel_MouseLeftButtonDown">
....
</StackPanel>

And the event handler code-behind: 以及事件处理程序的代码背后:

 private void StackPanel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            StackPanel panel = sender as StackPanel;
            if(panel==null)return;
            MyTreeViewItem myClicked = panel.DataContext as MyTreeViewItem;
            if (myClicked == null) return;
...
}

MyTreeViewItem is my custom type for a data; MyTreeViewItem是我的数据自定义类型; myClicked now stores a data associated with the clicked tree item. myClicked现在存储与单击的树项目关联的数据。 Hope it will help someone like me. 希望它能帮助像我这样的人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM