C# TreeView使用技巧

简介:

节点勾选设置

TreeView树中节点勾选要求:

1、不选中一个节点,则其所有的子节点都不被选中。

2、选中一个节点,则其所有的子节点都被选中。

3、当一个节点的所有子节点都没有被选中时,该节点也没有被选中。

4、当一个节点的所有子节点中有一个被选中时,则该节点也被选中。

代码中对事件参数e.Action的判断,可以避免在改变节点的Checked的状态时,再次进入AfterCheck(),这样当在AfterCheck()中有其他逻辑响应时,可以做到每次勾选时,其他逻辑也只响应一次。

参考代码:

复制代码
        private void treeView_AfterCheck(object sender, TreeViewEventArgs e)
        {
            //通过鼠标或者键盘触发事件,防止修改节点的Checked状态时候再次进入
            if (e.Action == TreeViewAction.ByMouse || e.Action == TreeViewAction.ByKeyboard)
            {
                SetChildNodeCheckedState(e.Node, e.Node.Checked);
                SetParentNodeCheckedState(e.Node, e.Node.Checked);
            }
        }

        //设置子节点状态
        private void SetChildNodeCheckedState(TreeNode currNode, bool isCheckedOrNot)
        {
            if (currNode.Nodes == null) return; //没有子节点返回
            foreach (TreeNode tmpNode in currNode.Nodes)
            {
                tmpNode.Checked = isCheckedOrNot;
                SetChildNodeCheckedState(tmpNode, isCheckedOrNot);
            }
        }

        //设置父节点状态
        private void SetParentNodeCheckedState(TreeNode currNode, bool isCheckedOrNot)
        {
            if (currNode.Parent == null) return; //没有父节点返回
            if (isCheckedOrNot) //如果当前节点被选中,则设置所有父节点都被选中
            {
                currNode.Parent.Checked = isCheckedOrNot;
                SetParentNodeCheckedState(currNode.Parent, isCheckedOrNot);
            }
            else //如果当前节点没有被选中,则当其父节点的子节点有一个被选中时,父节点被选中,否则父节点不被选中
            {
                bool checkedFlag = false;
                foreach (TreeNode tmpNode in currNode.Parent.Nodes)
                {
                    if (tmpNode.Checked)
                    {
                        checkedFlag = true;
                        break;
                    }
                }
                currNode.Parent.Checked = checkedFlag;
                SetParentNodeCheckedState(currNode.Parent, checkedFlag);
            }
        }
复制代码

TreeView隐藏部分节点

WinForm中的TreeView没法根据每个节点的情况设置是否有checkbox,只能用CheckBoxes设置整个树是否有Checkbox,可通过如下方式隐藏部分节点的checkbox。

this.treeView1.CheckBoxes = true;
this.treeView1.DrawMode = TreeViewDrawMode.OwnerDrawAll;
this.treeView1.DrawNode += new DrawTreeNodeEventHandler(treeView1_DrawNode);

隐藏节点:

复制代码
        void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e)
        {
            //隐藏节点前的checkbox
            if (e.Node.Level == 0 || e.Node.Level == 1)
                HideCheckBox(this.treeView1, e.Node);
            e.DrawDefault = true;
        }

        [StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Auto)]
        private struct TVITEM
        {
            public int mask;
            public IntPtr hItem;
            public int state;
            public int stateMask;
            [MarshalAs(UnmanagedType.LPTStr)]
            public string lpszText;
            public int cchTextMax;
            public int iImage;
            public int iSelectedImage;
            public int cChildren;
            public IntPtr lParam;
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, ref TVITEM lParam);

        private const int TVIF_STATE = 0x8;
        private const int TVIS_STATEIMAGEMASK = 0xF000;
        private const int TV_FIRST = 0x1100;
        private const int TVM_SETITEM = TV_FIRST + 63;

        private void HideCheckBox(TreeView tvw, TreeNode node)
        {
            TVITEM tvi = new TVITEM();
            tvi.hItem = node.Handle;
            tvi.mask = TVIF_STATE;
            tvi.stateMask = TVIS_STATEIMAGEMASK;
            tvi.state = 0;
            SendMessage(tvw.Handle, TVM_SETITEM, IntPtr.Zero, ref tvi);
        }
复制代码

TreeView递归加载节点

C#遍历指定文件夹下所有子文件夹及文件并添加到目录树:

复制代码
    private void Form1_Load(object sender, EventArgs e)
        {
            TreeNode root = new TreeNode();
           //根目录名称
            root.Text = "目录";
           //根目录路径
            GetFiles(@"E:\Tools", root);
            treeView1.Nodes.Add(root);
        }

        private void GetFiles(string filePath, TreeNode node)
        {
            DirectoryInfo folder = new DirectoryInfo(filePath);
            node.Text = folder.Name;
            node.Tag = folder.FullName;
            
            FileInfo[] chldFiles = folder.GetFiles("*.*");
            foreach (FileInfo chlFile in chldFiles)
            {
                TreeNode chldNode = new TreeNode();
                chldNode.Text = chlFile.Name;
                chldNode.Tag = chlFile.FullName;
                node.Nodes.Add(chldNode);
            }

            DirectoryInfo[] chldFolders = folder.GetDirectories();
            foreach (DirectoryInfo chldFolder in chldFolders)
            {
                TreeNode chldNode = new TreeNode();
                chldNode.Text = folder.Name;
                chldNode.Tag = folder.FullName;
                node.Nodes.Add(chldNode);
                GetFiles(chldFolder.FullName, chldNode);
            }
        }
复制代码

 

 

 

作者: 阿凡卢
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
http://www.cnblogs.com/luxiaoxun/p/3288003.html
相关文章
|
1月前
|
C# 数据库
40.c#:TreeView 控件
40.c#:TreeView 控件
14 1
|
数据处理 C#
C#-TreeView
TreeView是一个树形结构的控件,能够表现出对象的层级关系,比如文件夹目录展示经常使用。
89 0
|
存储 C#
C#(三十)之C#comboBox ListView treeView
本篇内容记录了comboBox下拉列表框属性、ListView 列表视图属性、ListView 列表视图事件、treeView树状视图属性。
222 0
C#(三十)之C#comboBox ListView treeView
WinForm——TreeView总结
WinForm——TreeView总结
381 0
|
C#
Seaching TreeVIew WPF
原文:Seaching TreeVIew WPF 项目中有一个树形结构的资源,需要支持搜索功能,搜索出来的结果还是需要按照树形结构展示,下面是简单实现的demo。 1.首先创建TreeViewItem的ViewModel,一般情况下,树形结构都包含DisplayName,Deepth,Parent...
810 0
ListView、TreeView和DataGrid。
原文:ListView、TreeView和DataGrid。 1、ListView。 ListView继承自简单的没有特色的ListBox,并使用View属性进行扩展。增加了对基于列显示的支持,并增加了快速切换视图或显示模式的能力,而不需要重新绑定数据以及重新构建列表。
1188 0