using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel; namespace SimpleCustomControl
{
[ToolboxBitmap(typeof(TreeView))]
public partial class MyTreeView : TreeView
{
private int imageWidth = 0x12; private bool isFirstNodeDifferent = true;
[Category("行为"), DefaultValue(true), Description("确定根节点第一个节点是否作为取消所择使用。")]
public bool IsFirstNodeDifferent
{
get { return isFirstNodeDifferent; }
set { isFirstNodeDifferent = value; }
} public MyTreeView()
{
InitializeComponent();
// 如果更改 ImageList 中图片大小,此处设置可能有用.未测试.可注释掉.
imageWidth = imageList1.ImageSize.Width + ;
} //规则1:取消选定
//规则1.1:检查是否有子节点,需清除所有子节点的选定状态;
//规则1.2:检查是否有父节点,如有,则根据兄弟节点的选定状态修改父节点的选定状态
//规则2:选定
//规则2.1:检查是否有子节点,设置所有子节点为选定状态
//规则2.2:检查是否有父节点,如有,则根据兄弟节点的选定状态修改父节点的选定状态
/// <summary>
/// 鼠标点击节点触发事件
/// </summary>
private void MyTreeView_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 (isFirstNodeDifferent && e.Node.Level == && e.Node.Index == )
NodeUnSelected();
else
NodeClick(e.Node);
}
}
} /// <summary>
/// 节点点击
/// </summary>
/// <param name="tn">点击的节点</param>
public void NodeClick(TreeNode tn)
{
if (tn.ImageIndex == )
{
NodeUnSelected(tn);
}
else
{
NodeSelected(tn);
}
} /// <summary>
/// 不管现在节点状态
/// 将节点设置为选中
/// </summary>
/// <param name="tn">待更改状态的节点</param>
public void NodeSelected(TreeNode tn)
{
tn.SelectedImageIndex = ;
tn.ImageIndex = ;
SetNodeImg21(tn);
SetNodeImg22(tn);
} /// <summary>
/// 不管现在节点状态
/// 去掉节点选中状态
/// </summary>
/// <param name="tn">待更改状态的节点</param>
public void NodeUnSelected(TreeNode tn)
{
tn.SelectedImageIndex = ;
tn.ImageIndex = ;
SetNodeImg11(tn);
SetNodeImg12(tn);
} /// <summary>
/// 查找节点状态 是否被选中
/// </summary>
/// <param name="tn">查看的节点</param>
/// <returns>节点是否被选中</returns>
public bool NodeIsChecked(TreeNode tn)
{
if (tn.ImageIndex == || tn.ImageIndex == )
return true;
return false;
} private bool nodeIsAllChecked;
/// <summary>
/// 返回整个TreeView 选中状态
/// </summary>
/// <returns>返回选中状态信息</returns>
[Browsable(false)]
public bool NodeIsAllChecked
{
get
{
if (isFirstNodeDifferent)
{
// 两种方式 两种效率 未测试哪个更效率
//foreach (TreeNode tn in Nodes)
//{
// if (tn.Index != 0 && NodeCheckState(tn) != CheckState.Checked)
// return false;
//}
int count = Nodes.Count;
for (int i = ; i < count; i++)
{
if (NodeCheckState(Nodes[i]) != CheckState.Checked)
return false;
}
}
else
{
foreach (TreeNode tn in Nodes)
{
if (NodeCheckState(tn) != CheckState.Checked)
return false;
}
}
return true;
}
} /// <summary>
/// 返回指定节点选中状态
/// 有三种状态 Checked 选中 Indeterminate 部分选中 Unchecked 未选中
/// </summary>
/// <param name="tn">节点是否被选中</param>
/// <returns>返回选中状态信息</returns>
public CheckState NodeCheckState(TreeNode tn)
{
switch (tn.ImageIndex)
{
case :
return CheckState.Indeterminate;
case :
return CheckState.Checked;
case :
default:
return CheckState.Unchecked;
}
} /// <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);
}
if (isFirstNodeDifferent && Nodes.Count > )
{
Nodes[].SelectedImageIndex = ;
Nodes[].ImageIndex = ;
}
} //设置节点选定状态:
//规则.1:检查是否有子节点,需清除所有子节点的选定状态;
void SetNodeImg11(TreeNode tn)
{
foreach (TreeNode t in tn.Nodes)
{
t.SelectedImageIndex = ;
t.ImageIndex = ;
if (t.Nodes.Count != )
SetNodeImg11(t);
}
} //设置节点选定状态:
//规则.2:检查是否有父节点,如有,则根据兄弟节点的选定状态修改父节点的选定状态
void SetNodeImg12(TreeNode tn)
{
if (tn.Parent == null)
return;
int Img0Num = , Img1Num = , Img2Num = ;
//统计同级节点选中情况
foreach (TreeNode t in tn.Parent.Nodes)
{
switch (t.ImageIndex)
{
case :
Img1Num++;
break;
case :
Img2Num++;
break;
case :
default:
Img0Num++;
break;
}
}
//如果同级节点选中和未选中的都有
if (Img1Num != || (Img0Num != && Img2Num != ))
{
tn.Parent.SelectedImageIndex = ;
tn.Parent.ImageIndex = ;
}
else
{
tn.Parent.StateImageIndex = ;
tn.Parent.ImageIndex = ;
}
SetNodeImg12(tn.Parent);
} //设置节点选定状态:
//规则.1:检查是否有子节点,设置所有子节点为选定状态
void SetNodeImg21(TreeNode tn)
{
foreach (TreeNode t in tn.Nodes)
{
t.SelectedImageIndex = ;
t.ImageIndex = ;
if (t.Nodes.Count != )
{
SetNodeImg21(t);
}
}
} //设置节点选定状态:
//规则.2:检查是否有父节点,如有,则根据兄弟节点的选定状态修改父节点的选定状态
void SetNodeImg22(TreeNode tn)
{
if (tn.Parent == null)
return;
int Img0Num = , Img1Num = , Img2Num = ;
foreach (TreeNode t in tn.Parent.Nodes)
{
//if (t.ImageIndex == 0)
// Img0Num++;
//if (t.ImageIndex == 1)
// Img1Num++;
//if (t.ImageIndex == 2)
// Img2Num++;
switch (t.ImageIndex)
{
case :
Img1Num++;
break;
case :
Img2Num++;
break;
case :
default:
Img0Num++;
break;
}
}
if (Img1Num != || (Img0Num != && Img2Num != ))
{
tn.Parent.SelectedImageIndex = ;
tn.Parent.ImageIndex = ;
}
//else if (Img1Num == 0 && Img2Num == 0)
//{
// tn.Parent.SelectedImageIndex = 0;
// tn.Parent.ImageIndex = 0;
//}
else
{
tn.Parent.StateImageIndex = ;
tn.Parent.ImageIndex = ;
}
SetNodeImg22(tn.Parent);
} }
}

TreeView 三种状态 没多大变化 只是增加了很多函数以方便调用的更多相关文章

  1. WinForm TreeView 三种状态

    private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { var node = e.N ...

  2. TreeView的三种状态,全选,全不选,半选中

    我知道的设置treeview节点的三种状态,如果不是买的控件,那么通过代码,只能设置两种状态,我知道的有三种方法, 第一种是重写treeview,第二种是把三种状态做成小图标,让节点复选框随着不同的状 ...

  3. hibernate 三种状态的转换

    一.遇到的神奇的事情 使用jpa操作数据库,当我使用findAll()方法查处一个List的对象后,给对这个list的实体进行了一些操作,并没有调用update 或者 saveOrUpdate方法,更 ...

  4. SSH框架之-hibernate 三种状态的转换

    一.遇到的神奇的事情 使用jpa操作数据库,当我使用findAll()方法查处一个List的对象后,给对这个list的实体进行了一些操作,并没有调用update 或者 saveOrUpdate方法,更 ...

  5. Hibernate 对象的三种状态

    hibernate对象的三种状态: (一) 瞬时(临时)状态:   对象被创建时的状态,数据库里面没有与之对应的记录! (二) 持久状态:   处于session的管理中,并且数据库里面存在与之对应的 ...

  6. Hibernate中对象的三种状态及相互转化

    1. 瞬时状态 (Transient) 当我们通过Java的new关键字来生成一个实体对象时,这时这个实体对象就处于自由状态,如下:  Customer customer=new Customer(“ ...

  7. 菜鸟学SSH(八)——Hibernate对象的三种状态

    前面写了几篇关于SSH的博客,但不是Struts就是Spring,Hibernate还从来没写过呢.说好是SSH的,怎么可以光写那两个,而不写Hibernate呢对吧.今天就先说说Hibernate对 ...

  8. java对象中的三种状态和脏检查及刷新缓存机制

    瞬时状态 瞬时状态又称临时状态.如果java对象与数据库中的数据没有任何的关联,即此java对象在数据库中没有相关联的记录,此时java对象的状态为瞬时状态,session对于 瞬时状态的ava对象是 ...

  9. Git 深度学习填坑之旅二(文件三种状态、打标签)

    0x01 三种状态 Git 有三种状态,你的文件可能处于其中之一: 已提交(committed).已修改(modified)和已暂存(staged). 已提交表示数据已经安全的保存在本地数据库中. 已 ...

随机推荐

  1. element-ui el-cascader级联选择器设置指定层级不能选中

    有时候用element-ui el-cascader级联选择器添加分类时会遇到最多添加几级的限定.看了文档,只要给需要禁止选择的选项添加disabled属性就可以.但是使用一层一层循环遍历数据感觉很麻 ...

  2. 【python+beautifulsoup4】Python中安装bs4后,pycharm报错ModuleNotFoundError: No module named 'bs4'

    本文主要分享关于在对应python版本中安装beautifulsoup之后,在代码执行时还会提示“No module named 'bs4'”的问题. 安装beautifsoup4 在命令窗口执行 p ...

  3. MyBatis 插入失败后爆出 500 ,如何捕获异常?

    我们在使用 Mybatis 的时候,会出现以下场景 数据表里有一些字段被设置为了 不可为 null 但是我们的用户在提交表单的时候没有提交所需的 字段数据 然后 Mybatis 在数据库做操作的时候就 ...

  4. deep_learning_学习资料

    TensorFlow的55个经典案例:https://blog.csdn.net/xzy_thu/article/details/76220654 吴恩达机器学习: 1.序列学习:https://mo ...

  5. 10_Redis_多数据库

    一:概念: 一个Redis实例可以包括多个数据库,客户端可以指定连接某个redis实例的哪个数据库,就好比一个mysql中创建多个数据库,客户端连接时指定连接哪个数据库. 一个Redis实例最多可提供 ...

  6. class文件与dex文件解析

    关于Android的热修复与插件化技术在如今基本上已经成为了“时髦技术”的标配了,或者说用来进行“炫技”的一种方式,毕境如今Android已经发展得非常之成熟了,基本上APP用的到东东都差不多,除了业 ...

  7. CF487E Tourists[圆方树+树剖(线段树套set)]

    做这题的时候有点怂..基本已经想到正解了..结果感觉做法有点假,还是看了正解题解.. 首先提到简单路径上经过的点,就想到了一个关于点双的结论:两点间简单路径上所有可能经过的点的并等于路径上所有点所在点 ...

  8. SpringBoot集成Druid实现监控

    application.properties文件完整信息 #连接数据库 spring.datasource.driver-class-name=org.mariadb.jdbc.Driver spri ...

  9. C# 操作服务命令

    安装服务 @echo.服务启动...... @echo off @sc create 服务名称 binPath= " exe地址" @net start 服务名称 @sc conf ...

  10. 题解 [AT2134] Zigzag MST

    题面 解析 我们先考虑一下加一条边(x,y,z)会成什么亚子: (还有很多边不画了...) 然后我们把这个图单独拿出来: 我们可以发现,对于最小生成树的贡献, 它是等价于下面这张图的(因为连通性一样) ...