winform中TreeView节点选中问题

qq_24360693 2017-10-11 10:36:09
TreeView开启节点复选框 CheckBoxes = true后,实现了功能勾选某个节点后自动勾选该节点的所有节点,然后出现了个问题,就是如果双击勾选框,那么该节点会先勾选再取消勾选,而他的子节点会变成勾选状态,此后再次单机该节点复选框,该节点复选框勾选状态不会改变,进行测试后发现在该节点勾选框上双击,checked属性只会改变一次,但复选框的显示勾选状态会改变两次(即节点checked属性和复选框显示状态不同),这个问题要怎么解决?尝试在节点勾选时将treeview设为enable = false依旧无法阻止节点复选框的双击
...全文
333 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_25147077 2017-10-11
  • 打赏
  • 举报
回复
可以选择屏蔽TreeView的双击动作,或者试试这篇缩写http://www.xuebuyuan.com/80983.html
qq_24360693 2017-10-11
  • 打赏
  • 举报
回复
引用 4 楼 xdashewan 的回复:
[quote=引用 3 楼 qq_24360693 的回复:] 在双击节点复选框的时候不会触发treeview的双击事件,但是双击后无论多久,再次单击就会触发treeview的双击事件,这也是个奇怪的问题
后面那个帖子我并没有尝试过,你只能自己试试。屏蔽对treeview的双击行为完全可行[/quote] 我尝试过,即便屏蔽双击事件也不行,因为根本没有引发treeview的双击事件,在节点的复选框中双击会触发两次节点单击事件但不会触发双击事件
qq_24360693 2017-10-11
  • 打赏
  • 举报
回复
引用 2 楼 xdashewan 的回复:
可以选择屏蔽TreeView的双击动作,或者试试这篇缩写http://www.xuebuyuan.com/80983.html
在双击节点复选框的时候不会触发treeview的双击事件,但是双击后无论多久,再次单击就会触发treeview的双击事件,这也是个奇怪的问题
qq_24360693 2017-10-11
  • 打赏
  • 举报
回复
简单说:treeview复选框未选中,双击treeview的节点复选框,结果复选框外观时未选中,但后台的值是选中的
xdashewan 2017-10-11
  • 打赏
  • 举报
回复
引用 3 楼 qq_24360693 的回复:
在双击节点复选框的时候不会触发treeview的双击事件,但是双击后无论多久,再次单击就会触发treeview的双击事件,这也是个奇怪的问题
后面那个帖子我并没有尝试过,你只能自己试试。屏蔽对treeview的双击行为完全可行
xdashewan 2017-10-11
  • 打赏
  • 举报
回复
可以选择屏蔽TreeView的双击动作,或者试试这篇缩写http://www.xuebuyuan.com/80983.html
qq_24360693 2017-10-11
  • 打赏
  • 举报
回复
引用 6 楼 xdashewan 的回复:
[quote=引用 5 楼 qq_24360693 的回复:] 我尝试过,即便屏蔽双击事件也不行,因为根本没有引发treeview的双击事件,在节点的复选框中双击会触发两次节点单击事件但不会触发双击事件
屏蔽的系统的双击消息,只要系统判定为双击,那么就会发送双击消息,屏蔽的就是此消息,我之前写的测试案例,你可以试一下

public partial class DoubleClickCatch : Form
    {
        private const int GWL_WNDPROC = -4;
        private const int WM_LBUTTONDBLCLK = 0x0203;

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, MyWndProc wndProc);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr CallWindowProc(IntPtr wndProc, IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

        public delegate IntPtr MyWndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

        private IntPtr ldWndProc = IntPtr.Zero;
        private IntPtr OldWndProc;
        private MyWndProc Wpr = null;

        public DoubleClickCatch()
        {
            InitializeComponent();
            InitializeThatControl();

        }

        private void InitializeThatControl()
        {
            this.Wpr = new MyWndProc(this.MyControlWndProc);
            this.OldWndProc = SetWindowLong(treeView1.Handle, GWL_WNDPROC, Wpr);
        }

        private IntPtr MyControlWndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam)
        {
            switch (msg)
            {
                case WM_LBUTTONDBLCLK:
                    label1.Text = "double click";
                    return (IntPtr)0;
                default:
                    return CallWindowProc(OldWndProc, hWnd, msg, wParam, lParam);
            }
        }

        private void ChangeChild(TreeNode node, bool state)
        {
            node.Checked = state;
            foreach (TreeNode tn in node.Nodes)
                ChangeChild(tn, state);
        }

        private void ChangeParent(TreeNode node)
        {
            if (node.Parent != null)
            {
                int brotherNodeCheckedCount = 0;
                foreach (TreeNode tn in node.Parent.Nodes)
                {
                    if (tn.Checked == true)
                        brotherNodeCheckedCount++;
                }
                if (brotherNodeCheckedCount == 0)
                {
                    node.Parent.Checked = false;
                    ChangeParent(node.Parent);
                }
                if (brotherNodeCheckedCount >= 1)
                {
                    node.Parent.Checked = true;
                    ChangeParent(node.Parent);
                }
            }
        }

        private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Node.Parent != null)
            {
                ChangeParent(e.Node);
            }
            if (e.Node.GetNodeCount(false) > 0)
            {
                ChangeChild(e.Node, e.Node.Checked);
            }
        }
    }
[/quote] 老哥啊,这个系统本身就没有把他判断成双击啊,实际操作是双击,但是系统把他判断成两次单击 http://www.cnblogs.com/sqshine/archive/2008/12/29/1364236.html 我这边在aftercheck的时候执行了这个,你可以尝试一下,然后去双击节点的复选框,监视一下你双击的这个节点的checked属性,就知道问题了。
xdashewan 2017-10-11
  • 打赏
  • 举报
回复
引用 5 楼 qq_24360693 的回复:
我尝试过,即便屏蔽双击事件也不行,因为根本没有引发treeview的双击事件,在节点的复选框中双击会触发两次节点单击事件但不会触发双击事件
屏蔽的系统的双击消息,只要系统判定为双击,那么就会发送双击消息,屏蔽的就是此消息,我之前写的测试案例,你可以试一下

public partial class DoubleClickCatch : Form
    {
        private const int GWL_WNDPROC = -4;
        private const int WM_LBUTTONDBLCLK = 0x0203;

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, MyWndProc wndProc);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr CallWindowProc(IntPtr wndProc, IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

        public delegate IntPtr MyWndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

        private IntPtr ldWndProc = IntPtr.Zero;
        private IntPtr OldWndProc;
        private MyWndProc Wpr = null;

        public DoubleClickCatch()
        {
            InitializeComponent();
            InitializeThatControl();

        }

        private void InitializeThatControl()
        {
            this.Wpr = new MyWndProc(this.MyControlWndProc);
            this.OldWndProc = SetWindowLong(treeView1.Handle, GWL_WNDPROC, Wpr);
        }

        private IntPtr MyControlWndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam)
        {
            switch (msg)
            {
                case WM_LBUTTONDBLCLK:
                    label1.Text = "double click";
                    return (IntPtr)0;
                default:
                    return CallWindowProc(OldWndProc, hWnd, msg, wParam, lParam);
            }
        }

        private void ChangeChild(TreeNode node, bool state)
        {
            node.Checked = state;
            foreach (TreeNode tn in node.Nodes)
                ChangeChild(tn, state);
        }

        private void ChangeParent(TreeNode node)
        {
            if (node.Parent != null)
            {
                int brotherNodeCheckedCount = 0;
                foreach (TreeNode tn in node.Parent.Nodes)
                {
                    if (tn.Checked == true)
                        brotherNodeCheckedCount++;
                }
                if (brotherNodeCheckedCount == 0)
                {
                    node.Parent.Checked = false;
                    ChangeParent(node.Parent);
                }
                if (brotherNodeCheckedCount >= 1)
                {
                    node.Parent.Checked = true;
                    ChangeParent(node.Parent);
                }
            }
        }

        private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Node.Parent != null)
            {
                ChangeParent(e.Node);
            }
            if (e.Node.GetNodeCount(false) > 0)
            {
                ChangeChild(e.Node, e.Node.Checked);
            }
        }
    }

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧