• [QS] 同一个UI多个拥有右键菜单功能及数据拖动功能的Datagrid出现的假死问题


    场景
    多个DataGrid,每个Datagrid拥有右键菜单功能及数据拖动功能,会出现界面假死情况,如下图所示,第三步骤点击DataGrid one时将不会有任何反应,使用snoop查看事件发现,第二步操作后,DataGrid Two就没有释放鼠标捕捉
    操作步骤
    为了方便,直接上图,共三个步骤,如下所示:


    相关后台代码:

        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
    
                var ls = new List<string> {"ss1", "ss2", "ss3"};
                dg1.ItemsSource = ls;
                var ls1 = new List<string> { "ss1", "ss2"};
                dg2.ItemsSource = ls1;
    
                dg1.ContextMenu=new ContextMenu();
                dg1.ContextMenu.Items.Add("con1");
                dg1.ContextMenu.Items.Add("con1");
                dg1.ContextMenu.Items.Add("con1");
    
                dg1.MouseMove += dg1_MouseMove;
                dg2.MouseMove += dg2_MouseMove;
            }
    
    
            void dg2_MouseMove(object sender, MouseEventArgs e)
            {
                if (e.LeftButton == MouseButtonState.Pressed && dg2.IsKeyboardFocusWithin)
                {
                    var item = dg2.GetMouseTargetItem(e.GetPosition) as DataGridRow;
    
                    if (null != item && item.IsSelected)
                    {
                        DragDrop.DoDragDrop(dg2, dg2.SelectedItem, DragDropEffects.Move);
                        //dg2.CaptureMouse();
                        //dg2.ReleaseMouseCapture();
                        e.Handled = true;
                    }
                }
            }
    
            void dg1_MouseMove(object sender, MouseEventArgs e)
            {
                if (e.LeftButton == MouseButtonState.Pressed && dg1.IsKeyboardFocusWithin)
                {
                    var item = dg1.GetMouseTargetItem(e.GetPosition) as DataGridRow;
    
                    if (null != item && item.IsSelected)
                    {
                        DragDrop.DoDragDrop(dg1, dg1.SelectedItem, DragDropEffects.Move);
                        e.Handled = true;
                    }
                }
            }
    
        }
    
        public static class SelectorExtend
        {
            public delegate Point GetPosition(IInputElement element);
    
            private static DependencyObject GetItemByIndex(this Selector selector, int index)
            {
                if (null == selector)
                    return null;
                if (selector.ItemContainerGenerator.Status
                    != GeneratorStatus.ContainersGenerated)
                    return null;
                return selector.ItemContainerGenerator.ContainerFromIndex(index);
            }
    
            private static bool IsMouseTargetItem(Visual theTarget, GetPosition pos)
            {
                if (null == theTarget)
                    return false;
                Rect rect = VisualTreeHelper.GetDescendantBounds(theTarget);
                Point point = pos((IInputElement)theTarget);
                return rect.Contains(point);
            }
    
            public static object GetMouseTargetItem(this Selector selector, GetPosition pos)
            {
                if (null == selector)
                    return null;
                for (int i = 0; i < selector.Items.Count; i++)
                {
                    var itm = selector.GetItemByIndex(i);
                    if (IsMouseTargetItem(itm as Visual, pos))
                    {
                        return itm;
                    }
                }
                return null;
            }
        }
    

    解决方案
    即为代码中注释的两行代码,具体为什么,实话说,我也不是很清楚,该问题困扰了好几天,作过各种代码尝试,如,只有release的情况,是无效的,调试源码也未能发现问题所在,只有两行都加的情况下才能有效,若有大神能观察到其中的问题所在,求教,本人将不胜感激。

  • 相关阅读:
    windows7上使用docker容器
    centos7 docker镜像加速器配置
    用列表生成器打印九九乘法表
    -bash: wget: command not found的两种解决方法
    centos7 Dockerfile安装nginx
    centos6.5关闭防火墙命令
    centos7开机启动tomcat7
    centos7安装tomcat7
    CentOS7防火墙firewalld
    poj_3662 最小化第k大的值
  • 原文地址:https://www.cnblogs.com/maigc249/p/5528511.html
Copyright © 2020-2023  润新知