* UITreeView: CheckBoxes增加三态,感谢群友:笑口常开
This commit is contained in:
parent
37aacb0c13
commit
013b5084e1
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -20,14 +20,18 @@
|
||||
* 2020-07-07: V2.2.6 全部重写,增加圆角,CheckBoxes等
|
||||
* 2020-08-12: V2.2.7 更新可设置背景色
|
||||
* 2021-07-19: V3.0.5 调整了显示CheckBoxes时图片位置
|
||||
* 2021-08-26: V3.0.6 CheckBoxes增加三态,感谢群友:笑口常开
|
||||
******************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Design;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Sunny.UI
|
||||
@ -698,12 +702,13 @@ namespace Sunny.UI
|
||||
{
|
||||
base.OnDrawNode(e);
|
||||
|
||||
if (e.Node == null) return;
|
||||
if (e.Node == null || Nodes.Count == 0) return;
|
||||
|
||||
try
|
||||
{
|
||||
if (BorderStyle == BorderStyle.Fixed3D) BorderStyle = BorderStyle.FixedSingle;
|
||||
|
||||
if (e.Node == null || e.Node.Bounds.Width <= 0 && e.Node.Bounds.Height <= 0 && e.Node.Bounds.X <= 0 &&
|
||||
e.Node.Bounds.Y <= 0)
|
||||
if (e.Node == null || e.Node.Bounds.Width <= 0 && e.Node.Bounds.Height <= 0 && e.Node.Bounds.X <= 0 && e.Node.Bounds.Y <= 0)
|
||||
{
|
||||
e.DrawDefault = true;
|
||||
}
|
||||
@ -729,6 +734,8 @@ namespace Sunny.UI
|
||||
}
|
||||
|
||||
var checkboxColor = ForeColor;
|
||||
if (e.Node != null)
|
||||
{
|
||||
if (e.Node == SelectedNode)
|
||||
{
|
||||
e.Graphics.FillRectangle((e.State & TreeNodeStates.Hot) != 0 ? HoverColor : SelectedColor,
|
||||
@ -768,12 +775,12 @@ namespace Sunny.UI
|
||||
if (CheckBoxes)
|
||||
{
|
||||
if (!e.Node.Checked)
|
||||
using (var pn = new Pen(checkboxColor, 1))
|
||||
{
|
||||
e.Graphics.DrawRectangle(pn,
|
||||
e.Graphics.DrawRectangle(checkboxColor,
|
||||
new Rectangle(checkBoxLeft + 2, e.Bounds.Y + (ItemHeight - 12) / 2 - 1, 12, 12));
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var pn = new Pen(checkboxColor, 2))
|
||||
{
|
||||
var pt1 = new Point(checkBoxLeft + 2 + 2, e.Bounds.Y + (ItemHeight - 12) / 2 - 1 + 5);
|
||||
@ -790,10 +797,27 @@ namespace Sunny.UI
|
||||
}
|
||||
}
|
||||
|
||||
if (!DicNodeStatus.Keys.Contains(e.Node.GetHashCode()))
|
||||
{
|
||||
DicNodeStatus.Add(e.Node.GetHashCode(), false);
|
||||
}
|
||||
|
||||
if (DicNodeStatus[e.Node.GetHashCode()])
|
||||
{
|
||||
var location = e.Node.Bounds.Location;
|
||||
location.Offset(-29, 10);
|
||||
var size = new Size(7, 7);
|
||||
e.Graphics.FillRectangle(checkboxColor, new Rectangle(location, size)); //这里绘制的是正方形
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var lineY = e.Bounds.Y + e.Node.Bounds.Height / 2 - 1;
|
||||
var lineX = 3 + e.Node.Level * Indent + 9;
|
||||
|
||||
if (ShowLinesEx)
|
||||
{
|
||||
try
|
||||
{
|
||||
//绘制虚线
|
||||
@ -812,16 +836,21 @@ namespace Sunny.UI
|
||||
{
|
||||
lineX -= Indent;
|
||||
|
||||
if (pNode != null && Nodes.Count > 0)
|
||||
{
|
||||
if (pNode.NextNode != null)
|
||||
e.Graphics.DrawLine(pn, lineX, lineY, lineX, e.Node.Bounds.Top);
|
||||
|
||||
if (pNode.NextNode != null)
|
||||
e.Graphics.DrawLine(pn, lineX, lineY, lineX, e.Node.Bounds.Bottom);
|
||||
}
|
||||
|
||||
pNode = pNode.Parent;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (e.Node != null && Nodes.Count > 0)
|
||||
{
|
||||
if (e.Node.PrevNode != null)
|
||||
e.Graphics.DrawLine(pn, lineX, lineY, lineX, e.Node.Bounds.Top);
|
||||
@ -829,6 +858,7 @@ namespace Sunny.UI
|
||||
if (e.Node.NextNode != null)
|
||||
e.Graphics.DrawLine(pn, lineX, lineY, lineX, e.Node.Bounds.Bottom);
|
||||
}
|
||||
}
|
||||
|
||||
pn.Dispose();
|
||||
}
|
||||
@ -836,6 +866,7 @@ namespace Sunny.UI
|
||||
{
|
||||
Console.WriteLine(exception);
|
||||
}
|
||||
}
|
||||
|
||||
lineX = 3 + e.Node.Level * Indent + 9;
|
||||
//绘制左侧+号
|
||||
@ -849,6 +880,11 @@ namespace Sunny.UI
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private bool TreeNodeSelected(DrawTreeNodeEventArgs e)
|
||||
{
|
||||
@ -867,6 +903,74 @@ namespace Sunny.UI
|
||||
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
|
||||
private Dictionary<int, bool> DicNodeStatus = new Dictionary<int, bool>();
|
||||
|
||||
protected override void OnAfterCheck(TreeViewEventArgs e)
|
||||
{
|
||||
|
||||
base.OnAfterCheck(e);
|
||||
if (e.Action == TreeViewAction.ByMouse) //鼠标点击
|
||||
{
|
||||
DicNodeStatus[e.Node.GetHashCode()] = false;
|
||||
|
||||
SetChildNodeCheckedState(e.Node, e.Node.Checked);
|
||||
if (e.Node.Parent != null)
|
||||
{
|
||||
SetParentNodeCheckedState(e.Node);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void SetParentNodeCheckedState(TreeNode currNode)
|
||||
{
|
||||
TreeNode parentNode = currNode.Parent; //获得当前节点的父节点
|
||||
|
||||
var count = parentNode.Nodes.Cast<TreeNode>().Where(n => n.Checked).ToList().Count;
|
||||
|
||||
parentNode.Checked = count == parentNode.Nodes.Count;
|
||||
|
||||
var half = parentNode.Nodes.Cast<TreeNode>().Where(n => DicNodeStatus[n.GetHashCode()]).ToList().Count;
|
||||
|
||||
if ((count > 0 && count < parentNode.Nodes.Count) || half > 0)
|
||||
{
|
||||
DicNodeStatus[parentNode.GetHashCode()] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
DicNodeStatus[parentNode.GetHashCode()] = false;
|
||||
}
|
||||
|
||||
|
||||
var g = CreateGraphics();
|
||||
OnDrawNode(new DrawTreeNodeEventArgs(g, parentNode,
|
||||
new Rectangle(0, parentNode.Bounds.Y, Width, parentNode.Bounds.Height), TreeNodeStates.Hot));
|
||||
g.Dispose();
|
||||
|
||||
|
||||
if (parentNode.Parent != null) //如果父节点之上还有父节点
|
||||
{
|
||||
SetParentNodeCheckedState(parentNode); //递归调用
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//选中节点之后,选中节点的所有子节点
|
||||
private void SetChildNodeCheckedState(TreeNode currNode, bool state)
|
||||
{
|
||||
TreeNodeCollection nodes = currNode.Nodes; //获取所有子节点
|
||||
if (nodes.Count > 0) //存在子节点
|
||||
{
|
||||
foreach (TreeNode tn in nodes)
|
||||
{
|
||||
DicNodeStatus[tn.GetHashCode()] = false;
|
||||
tn.Checked = state;
|
||||
SetChildNodeCheckedState(tn, state);//递归调用子节点的子节点
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -21,7 +21,7 @@
|
||||
* 2021-06-20: V3.0.4 增加标题行,替代UITitlePage
|
||||
* 2021-07-18: V3.0.5 修复OnLoad在加载时重复加载两次的问题,增加Final函数,每次页面切换,退出页面都会执行
|
||||
* 2021-08-17: V3.0.6 增加TitleFont属性
|
||||
* 2021-08-24: V3.0.3 修复OnLoad在加载时重复加载两次的问题
|
||||
* 2021-08-24: V3.0.6 修复OnLoad在加载时重复加载两次的问题
|
||||
******************************************************************************/
|
||||
|
||||
using System;
|
||||
|
Loading…
x
Reference in New Issue
Block a user