参考了网上的一些例子,修改了一下。可以实现全选,全部去选,反选等功能。效果如附件图。
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();
}
}
}
- 大小: 15.9 KB
分享到:
相关推荐
2、纯粹的三态树结构,未添加父子节点联动等效果,给控件使用者更多的自由 3、增加三态的树节点类型,直接把状态保存在树节点中,而不是勉强地在treeview控件里面打补丁,使用更流畅 4、应用csc3.5的技术,直接扩展...
1:三态树:实现树控件的三态方式实现。 2:只读树:实现select和checkbox控制,同时解决树控件只读时滚动条无法使用的缺陷。 3:只核选一个节点:只可CheckBox一个节点,其它自动却除,从而实现唯一性Check。
2、纯粹的三态树结构,未添加父子节点联动等效果,给控件使用者更多的自由 3、增加三态的树节点类型,直接把状态保存在树节点中,而不是勉强地在treeview控件里面打补丁,使用更流畅 4、应用csc3.5的技术,直接扩展...
`TriStateTreeView.cs`文件是C#源代码文件,它包含了三态树控件的实现。代码中可能定义了一个名为`TriStateTreeView`的类,继承自.NET Framework的`TreeView`类。在这个类中,开发者可能实现了以下关键功能: 1. **...
三态树:实现树控件的三态方式实现。只读树:实现select和heckbox控制,同时解决树控件只读时滚动条无法使用的缺陷。 只核选一个节点:只可CheckBox一个节点,其它自动却除,从而实现唯一性Check。
在这个特定的案例中,"TreeView控件实现带复选框的三态树"是一个用于VSTO任务窗格的高级功能,它允许用户以图形化的方式查看和管理数据结构,特别是当数据组织成层次结构时非常有用。本文将深入探讨如何实现这样一个...
在这个特定的案例中,我们关注的是“支持三态的树和复选框”。这个标题暗示了一个功能强大的工具,它允许用户在Swing应用中使用具有三种状态的JTree和JCheckBox组件。 首先,让我们详细解释“三态”概念。在计算机...
"C#树型菜单控件实例"指的是使用C#编程实现的一种交互式UI组件,它呈现为一个多级结构,类似于文件系统的目录结构,用户可以通过展开和折叠节点来浏览和选择数据。 树型菜单控件(TreeView)是Windows Forms和WPF...
`Sources`目录可能包含了项目的所有源代码文件,而`SmartSolutions.Controls.Test`可能是测试目录,包含了针对这个三状态树控件的单元测试或者示例代码。 通过这个项目,开发者不仅可以了解如何扩展.NET控件以满足...
"三状态树视图控件(CustomTreeView)"是一个这样的实例,它由C#编程语言实现,专为显示三种不同状态的树形结构数据而设计。在这个项目中,开发者扩展了标准的.NET Framework TreeView控件,增加了更多的功能和灵活...
通过以上步骤,我们可以在C#中实现一个具备全选、未选和半选三种状态的TreeView控件。这样的功能可以极大地提高用户在处理复杂树形结构时的交互体验,特别是在需要独立控制每个节点及其子节点选中状态的情况下。
"TreeView实现三态"是指在TreeView控件中,节点不仅可以是常规的选中或未选中状态,还可以有第三种状态——部分选中(或者称为半选中)。这种三态模式在某些需求下特别有用,比如多选时允许用户选择一个组内的部分项...
"三态树视图"是一种在Windows应用程序中广泛使用的用户界面元素,特别是在C#和.NET框架下开发的WinForms应用中。它扩展了标准的树形视图控件,提供了更多的状态来表示节点的选中情况,从而为目录浏览和安装程序等...
《深入.NET平台和C#编程》内部测试机试题主要涵盖了三个方面的知识点,分别是:C#中的WinForms应用程序设计、面向对象编程(OOP)中的多态性和XML文件的读取与数据绑定。以下是对这些知识点的详细说明: 1. **C# ...
C#的泛型集合和多态性支持,为实现二叉树、平衡树、图的邻接矩阵和邻接列表提供了灵活的工具。书中还探讨了.NET框架中树形控件和图算法的使用。 3. **排序与查找算法**:这部分内容涵盖了各种排序和查找算法,包括...
9. **Lambda表达式与表达式树**:Lambda表达式简化了匿名函数的写法,而表达式树则用于表示代码本身的数据结构,常用于动态查询和元编程。 10. **.NET框架**:C#是.NET框架的一部分,理解.NET Framework的基本结构...
此外,面向对象编程是C#的一个重要组成部分,教程将涵盖类、对象、封装、继承和多态性等核心概念。通过理解这些,你可以创建可维护、可扩展的代码结构。 在C#版本的EventBus事件总线实例源码中,你将接触到事件驱动...