節點勾選設置
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); } }