zoukankan      html  css  js  c++  java
  • 在WPF的TreeView中实现右键选定

    在WPF中,TreeView默认情况是不支持右键选定的,也就是说,当右键点击某节点时,是无法选中该节点的。当我们想在TreeViewItem中实现右键菜单时,往往希望在弹出菜单的同时选中该节点,以使得菜单针对选中的节点生效。

        

    图1:虽然是在GNU节点上弹出的右键菜单,但选中的节点仍然是上次左键单击的DOC节点。
    图2:弹出的右键菜单同时选中GNU节点才是我们所需要的效果

    实现这个功能并不是很难,我最开始的做法就是目前网上流行的版本:

    1. 在TreeViewItem中响应PreviewMouseRightButtonDown事件
    2. 在响应右键单击事件前选中sender(TreeViewItem)节点。

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

    但这样做还存在一个问题:当选择子节点时,sender并不是子节点的TreeViewItem,而是其父节点。导致无法选择选择子节点。如下图所示:

      

    要解决这个问题也不难,那就是根据MouseButtonEventArgsOriginalSource来获取节点。但是OriginalSource也不是TreeViewItem,而是产生鼠标事件的子控件,因此还得往上查找,从而找到所属的TreeViewItem。

    最终的解决方案如下:

    1. 在TreeViewItem中响应PreviewMouseRightButtonDown事件

    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <EventSetter Event="TreeViewItem.PreviewMouseRightButtonDown" Handler="TreeViewItem_PreviewMouseRightButtonDown"/>
        </Style>
    </TreeView.ItemContainerStyle>

    2. 在响应右键单击事件前选中TreeViewItem节点。

    private void TreeViewItem_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
    {
        var treeViewItem = VisualUpwardSearch<TreeViewItem>(e.OriginalSource as DependencyObject) as TreeViewItem;
        if (treeViewItem != null)
        {
            treeViewItem.Focus();
            e.Handled = true;
        }
    }

    static DependencyObject VisualUpwardSearch<T>(DependencyObject source)
    {
        while (source != null && source.GetType() != typeof(T))
            source = VisualTreeHelper.GetParent(source);

        return source;
    }

    现在才是一个比较完美的解决方案。  

  • 相关阅读:
    用 Python 带你看各国 GDP 变迁
    Fluent Interface(流式接口)
    probing privatePath如何作用于ASP.NET MVC View
    Word插入htm文件导致文本域动态增加的一个问题
    Visual Studio 2013附加进程调试IE加载的ActiveX Control无效解决方法
    Ubuntu下Chrome运行Silverlight程序
    Windows Phone Bing lock screen doesn't change解决方法
    SPClaimsUtility.AuthenticateFormsUser的证书验证问题
    Web Service Client使用Microsoft WSE 2.0
    Visual Studio 2013安装Update 3启动crash的解决方法
  • 原文地址:https://www.cnblogs.com/TianFang/p/1667153.html
Copyright © 2011-2022 走看看