参考了网上的一些例子,修改了一下。可以实现全选,全部去选,反选等功能。效果如附件图。
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
namespace WindowsApplication1.DCR.View
{
public partial class TriStateTreeView : TreeView
{
private const int STATE_UNCHECKED = 0; //unchecked state
private const int STATE_CHECKED = 1; //checked state
private const int STATE_MIXED = 2; //mixed state (indeterminate)
//create a new ThreeStateTreeView
public TriStateTreeView(): base()
{
}
public void UpdateView()
{
this.SetNodesState(this.Nodes);
}
public void SelectAll()
{
this.SetNodesState(this.Nodes,STATE_CHECKED);
}
public void UnselectAll()
{
this.SetNodesState(this.Nodes,STATE_UNCHECKED);
}
public void AntiSelect()
{
this.SetNodesToAntiState(this.Nodes);
}
//returns a value indicating if all children are checked
public static bool IsAllChildrenChecked(TreeNode parent)
{
return IsAllChildrenSame(parent, STATE_CHECKED);
}
//returns a value indicating if all children are unchecked
public static bool IsAllChildrenUnchecked(TreeNode parent)
{
return IsAllChildrenSame(parent, STATE_UNCHECKED);
}
//initialize all nodes state image
private void SetNodesState(TreeNodeCollection nodes,int state)
{
foreach (TreeNode node in nodes)
{
node.StateImageIndex = state;
if (state == STATE_CHECKED)
{
node.Checked = true;
}
else
{
node.Checked = false;
}
if (node.Nodes.Count != 0)
{
SetNodesState(node.Nodes, state);
}
}
}
private void SetNodesState(TreeNodeCollection nodes) {
foreach (TreeNode node in nodes)
{
if (node.Checked)
{
node.StateImageIndex = STATE_CHECKED;
}
else
{
node.StateImageIndex = STATE_UNCHECKED;
}
UpdateParent(node);
if (node.Nodes.Count != 0)
{
SetNodesState(node.Nodes);
}
}
}
private void SetNodesToAntiState(TreeNodeCollection nodes)
{
foreach (TreeNode node in nodes)
{
if (node.Checked)
{
node.StateImageIndex = STATE_UNCHECKED;
node.Checked = false;
}
else
{
node.StateImageIndex = STATE_CHECKED;
node.Checked = true;
}
UpdateParent(node);
if (node.Nodes.Count != 0)
{
SetNodesToAntiState(node.Nodes);
}
}
}
//update children state image with the parent value
private void UpdateChildren(TreeNode parent)
{
int state = parent.StateImageIndex;
foreach (TreeNode node in parent.Nodes)
{
node.StateImageIndex = state;
if (node.Nodes.Count != 0)
{
UpdateChildren(node);
}
}
}
//update parent state image base on the children state
private void UpdateParent(TreeNode child)
{
TreeNode parent = child.Parent;
if (parent == null)
{
return;
}
if (child.StateImageIndex == STATE_MIXED)
{
parent.StateImageIndex = STATE_MIXED;
}
else if (IsAllChildrenChecked(parent))
{
parent.StateImageIndex = STATE_CHECKED;
}
else if (IsAllChildrenUnchecked(parent))
{
parent.StateImageIndex = STATE_UNCHECKED;
}
else
{
parent.StateImageIndex = STATE_MIXED;
}
UpdateParent(parent);
}
//returns a value indicating if all children are in the same state
private static bool IsAllChildrenSame(TreeNode parent, int state)
{
foreach (TreeNode node in parent.Nodes)
{
if (node.StateImageIndex != state)
{
return false;
}
if (node.Nodes.Count != 0 && !IsAllChildrenSame(node, state))
{
return false;
}
}
return true;
}
//build the checked, unchecked and indeterminate images
private static Image GetStateImage(CheckBoxState state, Size imageSize)
{
Bitmap bmp = new Bitmap(16, 16);
using (Graphics g = Graphics.FromImage(bmp))
{
Point pt = new Point((16 - imageSize.Width) / 2, (16 - imageSize.Height) / 2);
CheckBoxRenderer.DrawCheckBox(g, pt, state);
}
return bmp;
}
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
this.StateImageList = new ImageList();
using (Graphics g = base.CreateGraphics())
{
Size glyphSize = CheckBoxRenderer.GetGlyphSize(g, CheckBoxState.UncheckedNormal);
this.StateImageList.Images.Add(GetStateImage(CheckBoxState.UncheckedNormal, glyphSize));
this.StateImageList.Images.Add(GetStateImage(CheckBoxState.CheckedNormal, glyphSize));
this.StateImageList.Images.Add(GetStateImage(CheckBoxState.MixedNormal, glyphSize));
this.StateImageList.Images.Add(GetStateImage(CheckBoxState.UncheckedDisabled, glyphSize));
this.StateImageList.Images.Add(GetStateImage(CheckBoxState.CheckedDisabled, glyphSize));
this.StateImageList.Images.Add(GetStateImage(CheckBoxState.MixedDisabled, glyphSize));
}
}
//check if user click on the state image
protected override void OnMouseClick(MouseEventArgs e)
{
base.OnMouseClick(e);
if (e.Button == MouseButtons.Left)
{
TreeViewHitTestInfo info = base.HitTest(e.Location);
if (info.Node != null && info.Location == TreeViewHitTestLocations.StateImage)
{
TreeNode node = info.Node;
switch (node.StateImageIndex)
{
case STATE_UNCHECKED:
case STATE_MIXED:
node.StateImageIndex = STATE_CHECKED;
break;
case STATE_CHECKED:
node.StateImageIndex = STATE_UNCHECKED;
break;
}
UpdateChildren(node);
UpdateParent(node);
}
}
}
//check if user press the space key
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (e.KeyCode == Keys.Space)
{
if (base.SelectedNode != null)
{
TreeNode node = base.SelectedNode;
switch (node.StateImageIndex)
{
case STATE_UNCHECKED:
case STATE_MIXED:
node.StateImageIndex = STATE_CHECKED;
break;
case STATE_CHECKED:
node.StateImageIndex = STATE_UNCHECKED;
break;
}
UpdateChildren(node);
UpdateParent(node);
}
}
}
//swap between enabled and disabled images
protected override void OnEnabledChanged(EventArgs e)
{
base.OnEnabledChanged(e);
for (int i = 0; i < 3; i++)
{
Image img = this.StateImageList.Images[0];
this.StateImageList.Images.RemoveAt(0);
this.StateImageList.Images.Add(img);
}
}
}
}
namespace WindowsApplication1.DCR.View
{
partial class TriStateTreeView
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region 组件设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}
示例代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
TreeNode root = new TreeNode("所有院系");
triStateTreeView.Nodes.Add(root);
TreeNode xi1 = new TreeNode("中文系");
root.Nodes.Add(xi1);
TreeNode xi2 = new TreeNode("数学系");
root.Nodes.Add(xi2);
TreeNode xi3 = new TreeNode("物理系");
root.Nodes.Add(xi3);
TreeNode ban1 = new TreeNode("中文一班");
xi1.Nodes.Add(ban1);
TreeNode ban2 = new TreeNode("中文二班");
xi1.Nodes.Add(ban2);
TreeNode ban3 = new TreeNode("中文三班");
xi1.Nodes.Add(ban3);
ban3.Checked = true;
triStateTreeView.UpdateView();
}
private void buttonSelectAll_Click(object sender, EventArgs e)
{
this.triStateTreeView.SelectAll();
}
private void buttonUnSelectAll_Click(object sender, EventArgs e)
{
this.triStateTreeView.UnselectAll();
}
private void buttonAntiSelect_Click(object sender, EventArgs e)
{
this.triStateTreeView.AntiSelect();
}
}
}
![点击查看原始大小图片](http://dl2.iteye.com/upload/attachment/0025/0807/ff861b2a-4e12-3518-a608-9a4ceab7c9af-thumb.jpg)
- 大小: 15.9 KB
分享到:
相关推荐
2、纯粹的三态树结构,未添加父子节点联动等效果,给控件使用者更多的自由 3、增加三态的树节点类型,直接把状态保存在树节点中,而不是勉强地在treeview控件里面打补丁,使用更流畅 4、应用csc3.5的技术,直接扩展...
1:三态树:实现树控件的三态方式实现。 2:只读树:实现select和checkbox控制,同时解决树控件只读时滚动条无法使用的缺陷。 3:只核选一个节点:只可CheckBox一个节点,其它自动却除,从而实现唯一性Check。
2、纯粹的三态树结构,未添加父子节点联动等效果,给控件使用者更多的自由 3、增加三态的树节点类型,直接把状态保存在树节点中,而不是勉强地在treeview控件里面打补丁,使用更流畅 4、应用csc3.5的技术,直接扩展...
三态树:实现树控件的三态方式实现。只读树:实现select和heckbox控制,同时解决树控件只读时滚动条无法使用的缺陷。 只核选一个节点:只可CheckBox一个节点,其它自动却除,从而实现唯一性Check。
此控件的的功能如下: 用三种不同的图片来表示子级全选,部分选择,还是本身选,
C# Excel开发 VSTO任务窗格TreeView控件实现带复选框的三态树设计。能够指示状态树的各种情况。全选、半选、未选。可以很方便的看到树内部的选择情况
C# 程序实现一个能够表示节点三种状态的树状控件,它继承与TreeView,它的三种状态为选中、非选中、部分节点选中.
一个强大的树控件,支持拖拽,右键菜单修改删除,支持ajax载入节点,支持图标,支持三态checkbox. 在线演示:http://www.astreeview.com
一个强大的树控件,支持拖拽,右键菜单修改删除,支持ajax载入节点,支持图标,支持三态checkbox.