三状态 TreeView 扩展
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; using System.ComponentModel; using System.Drawing; namespace UtilityClass { public class TreeViewEx : TreeView { private ImageList imageList1; private System.ComponentModel.IContainer components; [DefaultValue(false), Browsable(false)] public new bool CheckBoxes { get; private set; } private int imageWidth = 0x12 + 2; // 图片大小加空隙 //private bool isFirstDifferent = true; //[DefaultValue(true), Description("将第一个节点作为全选/全不选。")] //public bool IsFirstDifferent //{ get; set; } //{ // get // { // return isFirstDifferent; // } // set // { // if (isFirstDifferent != value) // isFirstDifferent = value; // } //} public TreeViewEx() { InitializeComponent(); // 防止图片过大 //imageWidth = imageList1.ImageSize.Width + 2; } //规则1:取消选定 //规则1.1:检查是否有子节点,需清除所有子节点的选定状态; //规则1.2:检查是否有父节点,如有,则根据兄弟节点的选定状态修改父节点的选定状态 //规则2:选定 //规则2.1:检查是否有子节点,设置所有子节点为选定状态 //规则2.2:检查是否有父节点,如有,则根据兄弟节点的选定状态修改父节点的选定状态 private void TreeViewEx_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { if (e.Button == MouseButtons.Left) { Rectangle rc = e.Node.Bounds; rc = new Rectangle(rc.X - imageWidth, rc.Y, rc.Width + imageWidth, rc.Height); if (rc.Contains(e.Location)) { //if (IsFirstDifferent && e.Node.Level == 0 && e.Node.Index == 0) if (e.Node.Level == 0 && e.Node.Index == 0) { if (e.Node.ImageIndex > 0) NodeUnSelected(); else NodeSelected(); } else NodeClick(e.Node); }} } /// <summary> /// 节点点击 /// </summary> /// <param name="tn">点击的节点</param> public void NodeClick(TreeNode tn) { if (tn.ImageIndex == 2) { NodeUnSelected(tn); } else { NodeSelected(tn); } } /// <summary> /// 不管现在节点状态 /// 将节点设置为选中 /// </summary> /// <param name="tn">待更改状态的节点</param> public void NodeSelected(TreeNode tn) { tn.SelectedImageIndex = 2; tn.ImageIndex = 2; SetNodeImg21(tn); SetNodeImg22(tn); } /// <summary> /// 不管现在节点状态 /// 去掉节点选中状态 /// </summary> /// <param name="tn">待更改状态的节点</param> public void NodeUnSelected(TreeNode tn) { tn.SelectedImageIndex = 0; tn.ImageIndex = 0; SetNodeImg11(tn); SetNodeImg12(tn); } /// <summary> /// 返回指定节点选中状态 /// 有三种状态 Unchecked 未选中 Indeterminate 部分选中 Checked 选中 /// </summary> /// <param name="tn">节点是否被选中</param> /// <returns>返回选中状态信息</returns> public CheckState NodeCheckState(TreeNode tn) { switch (tn.ImageIndex) { case 1: return CheckState.Indeterminate; case 2: return CheckState.Checked; case 0: default: return CheckState.Unchecked; } } /// <summary> /// 半选与全选返回 true 否则返回 false /// </summary> public bool IsChecked(TreeNode tn) { return tn.ImageIndex > 0; } /// <summary> /// 将所有子节点全不选 /// </summary> public void NodeUnSelected() { foreach (TreeNode tn in this.Nodes) { NodeUnSelected(tn); } } /// <summary> /// 将所有子节点全选 /// </summary> public void NodeSelected() { foreach (TreeNode tn in this.Nodes) { NodeSelected(tn); } } //设置节点选定状态: //规则.1:检查是否有子节点,需清除所有子节点的选定状态; void SetNodeImg11(TreeNode tn) { foreach (TreeNode t in tn.Nodes) { t.SelectedImageIndex = 0; t.ImageIndex = 0; if (t.Nodes.Count != 0) SetNodeImg11(t); } } //设置节点选定状态: //规则.2:检查是否有父节点,如有,则根据兄弟节点的选定状态修改父节点的选定状态 void SetNodeImg12(TreeNode tn) { if (tn.Parent == null) return; bool select = true; bool unselect = true; foreach (TreeNode t in tn.Parent.Nodes) { if (t.ImageIndex > 0) unselect = false; if (t.ImageIndex < 2) select = false; } if (select) { tn.Parent.SelectedImageIndex = 2; tn.Parent.ImageIndex = 2; } else if (unselect) { tn.Parent.SelectedImageIndex = 0; tn.Parent.ImageIndex = 0; } else { tn.Parent.SelectedImageIndex = 1; tn.Parent.ImageIndex = 1; } SetNodeImg12(tn.Parent); } //设置节点选定状态: //规则.1:检查是否有子节点,设置所有子节点为选定状态 void SetNodeImg21(TreeNode tn) { foreach (TreeNode t in tn.Nodes) { t.SelectedImageIndex = 2; t.ImageIndex = 2; if (t.Nodes.Count != 0) { SetNodeImg21(t); } } } //设置节点选定状态: //规则.2:检查是否有父节点,如有,则根据兄弟节点的选定状态修改父节点的选定状态 void SetNodeImg22(TreeNode tn) { if (tn.Parent == null) return; bool select = true; bool unselect = true; foreach (TreeNode t in tn.Parent.Nodes) { if (t.ImageIndex > 0) unselect = false; if (t.ImageIndex < 2) select = false; } if (select) { tn.Parent.SelectedImageIndex = 2; tn.Parent.ImageIndex = 2; } else if (unselect) { tn.Parent.SelectedImageIndex = 0; tn.Parent.ImageIndex = 0; } else { tn.Parent.SelectedImageIndex = 1; tn.Parent.ImageIndex = 1; } SetNodeImg22(tn.Parent); } private void InitializeComponent() { this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TreeViewEx)); this.imageList1 = new System.Windows.Forms.ImageList(this.components); this.SuspendLayout(); // // imageList1 // this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream"))); this.imageList1.TransparentColor = System.Drawing.Color.Transparent; this.imageList1.Images.SetKeyName(0, "CHECKBOX_NONE.png"); this.imageList1.Images.SetKeyName(1, "CHECKBOX_HALF.png"); this.imageList1.Images.SetKeyName(2, "CHECKBOX_ALL.png"); // // TreeViewEx // this.ImageIndex = 0; this.ImageList = this.imageList1; this.LineColor = System.Drawing.Color.Black; this.SelectedImageIndex = 0; this.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.TreeViewEx_NodeMouseClick); this.ResumeLayout(false); } } }



浙公网安备 33010602011771号