您的位置:首页 > 其它

在WPF中弹出右键菜单时判断鼠标是否选中该项

2016-07-25 11:10 344 查看
和上篇在WPF的TreeView中实现右键选定一样,这仍然是一个右键菜单的问题:

这个需求是在一个实现剪贴板的功能的时候遇到的:在弹出右键菜单时,如果菜单弹出位置在ListViewItem中时,我们认为这项已经被选中,可以使用剪贴板功能。





 

当菜单弹出位置在ListView的空白处时,我们一般认为没有项被选中,此时是不应该使能剪贴板功能的。





 

但是这个时候,该项仍然是选中的。不能通过Item的IsSelected的属性来区分这两种情况。这样,就需要我们加一个判断鼠标是否在所选的节点上的函数。实现这个功能的方式有如下两种:

方法1:响应ListView的PreviewMouseRightButtonDown事件,在其中判断是否有节点被选中。还是直接上代码吧:

   
bool isItemSelected = false;

    private void ListView_PreviewMouseRightButtonDown(object sender,
MouseButtonEventArgs e)

    {

        object item = GetElementFromPoint((ItemsControl)sender, e.GetPosition((ItemsControl)sender));

        isItemSelected = (item != null);

    }

    private object GetElementFromPoint(ItemsControl itemsControl,
Point point)

    {

        UIElement element = itemsControl.InputHitTest(point)
as UIElement;

        while (element !=
null)

        {

            if (element == itemsControl)

                return null;

            object item = itemsControl.ItemContainerGenerator.ItemFromContainer(element);

            if (!item.Equals(DependencyProperty.UnsetValue))

                return item;

            element = (UIElement)VisualTreeHelper.GetParent(element);

        }

        return null;

    }

这个其实就是一个命中测试的方面的问题,代码还是比较基础的,也没有什么需要解释的地方,但写起来还是有点麻烦。

方法2:同时响应ListView的PreviewMouseRightButtonDown事件和TreeViewItem的PreviewMouseRightButtonDown事件。

当鼠标点击在ListViewItem上时:发生的事件顺序为 ListView_MouseDown 、ListViewItem_MouseDown。
当鼠标点击在ListView外时:发生的事件仅为 ListView_MouseDown 。
因此,只要在ListView_MouseDown 中设置isItemSelected = false,在ListViewItem_MouseDown中设置isItemSelected =
true即可。由于非常简单,就不附代码了。

使用上面的两种方法后,就可以直接在剪切复制命令的CanExecute函数中通过isItemSelected来判断是否该使能剪切复制命令了。

另外,这两方法是针对ItemsControl类型的控件的,也就是说,在TreeView或ListBox等控件中也可以使用,如果把它们封装一下就更方便了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: