Files
KJD_WebService/TEMUKJD/UserComponent/UcTreeView.cs
T

770 lines
28 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Threading;
namespace TemuKJD.UserComponent
{
/// <summary>
/// 基于树视图的任务控件
/// </summary>
public partial class UcTreeView : TreeView
{
#region //construckor
/// <summary>
/// 自定义树视图控件构造函数
/// </summary>
public UcTreeView()
{
FullRowSelect = true;
ShowLines = true;
// 开启双缓冲等
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.EnableNotifyMessage | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true);
this.DrawMode = TreeViewDrawMode.OwnerDrawAll;
this.ItemHeight = 32;
this.ShowLines = true;
this.AfterExpand += UserTreeView_AfterExpand;
this.AfterSelect += UserTreeView_AfterSelect;
this.Layout += UserTreeView_Layout;
if (Properties.Resources.ResourceManager.GetObject("tree_default_icon_select") != null)
defaultNodeImageSelect = (Bitmap)Properties.Resources.ResourceManager.GetObject("tree_default_icon_select");
if (Properties.Resources.ResourceManager.GetObject("tree_default_icon") != null)
defaultNodeImage = (Bitmap)Properties.Resources.ResourceManager.GetObject("tree_default_icon");
}
protected override void OnNotifyMessage(Message m)
{
if (m.Msg != 0x14)
{
base.OnNotifyMessage(m);
}
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
private void UserTreeView_AfterSelect(object sender, TreeViewEventArgs e)
{
if (e.Node.Parent != null)
dicSelectNodeId[e.Node.Parent] = e.Node;
}
#endregion
#region //event
// 定义委托
public delegate void NodeGroupClickHandle(object sender, TreeViewEventArgs e);
// 定义事件
public event NodeGroupClickHandle NodeGroupClick;
// 执行事件
protected virtual void OnNodeGroupClick(TreeViewEventArgs e)
{
if (NodeGroupClick != null)
{
NodeGroupClick(this, e);
}
}
private void UserTreeView_Layout(object sender, LayoutEventArgs e)
{
if (!DesignMode)
{
foreach (TreeNode node in this.Nodes)
{
if (node != null)
{
if (allNodes.Contains(node) == false)
allNodes.Add(node);
}
foreach (TreeNode childNode in node.Nodes)
{
if (node == null)
continue;
if (!dicNodeImageSelect.Keys.Contains(childNode))
{
// 获取图标
if (Properties.Resources.ResourceManager.GetObject("tree_" + childNode.Text + "_select") != null)
{
var bitmap = (Bitmap)Properties.Resources.ResourceManager.GetObject("tree_" + childNode.Text + "_select");
dicNodeImageSelect[childNode] = bitmap;
}
}
if (!dicNodeImage.Keys.Contains(childNode))
{
// 获取图标
if (Properties.Resources.ResourceManager.GetObject("tree_" + childNode.Text) != null)
{
var bitmap = (Bitmap)Properties.Resources.ResourceManager.GetObject("tree_" + childNode.Text);
dicNodeImage[childNode] = bitmap;
}
}
}
}
}
}
private void UserTreeView_AfterExpand(object sender, TreeViewEventArgs e)
{
BeginUpdate();
if (HideCollapsedGroup && !DesignMode)
{
for (int i = 0; i < this.Nodes.Count; i++)
{
if (e.Node != this.Nodes[i])
{
this.Nodes.Remove(this.Nodes[i]);
i--;
}
}
}
foreach (TreeNode node in this.AllNodes)
{
if (node == null)
continue;
if (node != e.Node)
{
node.Collapse(true);
}
else
{
if (this.SelectedNode == null || this.SelectedNode.Parent == node)
continue;
else if (dicSelectNodeId.Keys.Contains(node))
this.SelectedNode = dicSelectNodeId[node];
else if (node.Nodes.Count > 0)
this.SelectedNode = node.Nodes[0];
}
}
EndUpdate();
}
#endregion
#region //field & property
private Bitmap defaultNodeImage;
private Bitmap defaultNodeImageSelect;
private List<TreeNode> lstTreeNode = new List<TreeNode>();
private Dictionary<TreeNode, TreeNode> dicSelectNodeId = new Dictionary<TreeNode, TreeNode>();
private Dictionary<TreeNode, Bitmap> dicNodeImage = new Dictionary<TreeNode, Bitmap>();
private Dictionary<TreeNode, Bitmap> dicNodeImageSelect = new Dictionary<TreeNode, Bitmap>();
/// <summary>
/// 展开按扭的大小
/// </summary>
private Size ExpandButtonSize = new Size(16, 16);
private Color _ExpandButtonColor = Color.FromArgb(255, 255, 255);
/// <summary>
/// 展开按扭颜色
/// </summary>
[Description("展开按扭颜色"), Category("UserProperty")]
public Color ExpandButtonColor
{
get
{
return _ExpandButtonColor;
}
set
{
if (_ExpandButtonColor != value)
{
_ExpandButtonColor = value;
this.Invalidate();
}
}
}
private Color _GroupBgColor = Color.FromArgb(249, 249, 249);
/// <summary>
/// 分组栏背景色
/// </summary>
[Description("分组栏背景色"), Category("UserProperty")]
public Color GroupBgColor
{
get
{
return _GroupBgColor;
}
set
{
if (_GroupBgColor != value)
{
_GroupBgColor = value;
this.Invalidate();
}
}
}
private Color _ChildNodeSelectedBgColor = Color.FromArgb(34, 148, 203);
/// <summary>
/// 子节点选中背景色
/// </summary>
[Description("子节点选中背景色"), Category("UserProperty")]
public Color ChildNodeSelectedBgColor
{
get
{
return this._ChildNodeSelectedBgColor;
}
set
{
if (_ChildNodeSelectedBgColor != value)
{
_ChildNodeSelectedBgColor = value;
this.Invalidate();
}
}
}
private Color _GroupTitleColor = Color.FromArgb(80, 80, 80);
/// <summary>
/// 分组栏标题色
/// </summary>
[Description("分组栏标题色"), Category("UserProperty")]
public Color GroupTitleColor
{
get
{
return _GroupTitleColor;
}
set
{
if (_GroupTitleColor != value)
{
_GroupTitleColor = value;
this.Invalidate();
}
}
}
private Color _OverForeColor = Color.FromArgb(235, 235, 235);
/// <summary>
/// 鼠标悬停色
/// </summary>
[Description("鼠标悬停色"), Category("UserProperty")]
public Color OverForeColor
{
get
{
return _OverForeColor;
}
set
{
if (_OverForeColor != value)
{
_OverForeColor = value;
this.Invalidate();
}
}
}
private Font groupFont = new Font("宋体", 10.5f);
/// <summary>
/// 组标题字体样式
/// </summary>
[Description("组标题字体样式"), Category("UserProperty")]
public Font GroupFont
{
get
{
return groupFont;
}
set
{
if (groupFont != value)
{
groupFont = value;
this.Invalidate();
}
}
}
private bool _HideCollpasedGroup = false;
[Description("隐藏折叠的组"), Category("UserProperty")]
public bool HideCollapsedGroup
{
get
{
return _HideCollpasedGroup;
}
set
{
if (_HideCollpasedGroup != value)
{
_HideCollpasedGroup = value;
this.Invalidate();
}
}
}
/// <summary>
/// 节点高度
/// </summary>
public new int ItemHeight
{
get
{
return base.ItemHeight;
}
set
{
if (base.ItemHeight != value && value >= 20)
{
base.ItemHeight = value;
this.Invalidate();
}
}
}
private List<TreeNode> allNodes = new List<TreeNode>();
/// <summary>
/// 所有节点列表
/// </summary>
public List<TreeNode> AllNodes { get { return allNodes; } }
#endregion
#region //override
protected override void OnDrawNode(DrawTreeNodeEventArgs e)
{
//base.OnDrawNode(e);
DrawNodeItem(e);
}
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0201)//单击
{
int wparam = m.LParam.ToInt32();
Point point = new Point(
LOWORD(wparam),
HIWORD(wparam));
//point = PointToClient(point);
TreeNode tn = this.GetNodeAt(point);
if (tn == null)
{
base.WndProc(ref m);
return;
}
if (tn.Level == 0)
{
if (tn.IsExpanded)
{
//tn.Collapse();
}
else
{
tn.Expand();
}
m.Result = IntPtr.Zero;
OnNodeGroupClick(new TreeViewEventArgs(tn, TreeViewAction.ByMouse));
return;
}
else
{
base.WndProc(ref m);
//tn.IsSelected = true;
//this.SelectedNode = tn;
}
this.SelectedNode = tn;
}
else if (m.Msg == 0x0203)//双击
{
int wparam = m.LParam.ToInt32();
Point point = new Point(
LOWORD(wparam),
HIWORD(wparam));
//point = PointToClient(point);
TreeNode tn = this.GetNodeAt(point);
if (tn == null)
{
base.WndProc(ref m);
return;
}
if (tn.Level == 0)
{
m.Result = IntPtr.Zero;
return;
}
else
{
base.WndProc(ref m);
}
this.SelectedNode = tn;
}
else if (m.Msg == 0x0200)//鼠标移动
{
try
{
int wparam = m.LParam.ToInt32();
Point point = new Point(
LOWORD(wparam),
HIWORD(wparam));
//point = PointToClient(point);
TreeNode tn = this.GetNodeAt(point);
if (tn == null)
{
Cursor = Cursors.Default;
// this.SelectedNode = null;
base.WndProc(ref m);
return;
}
Cursor = Cursors.Hand;
//this.SelectedNode = tn;
}
catch { }
}
else if (m.Msg == 0x02A3)//鼠标移出 WM_MOUSELEAVE = $02A3;
{
// this.SelectedNode = null;
base.WndProc(ref m);
return;
}
else
{
base.WndProc(ref m);
}
//WM_LBUTTONDOWN = $0201
//WM_LBUTTONDBLCLK = $0203;
}
#endregion
#region //private method
/// <summary>
/// 自定义绘制节点
/// </summary>
/// <param name="e"></param>
private void DrawNodeItem(DrawTreeNodeEventArgs e)
{
TreeNode tn = e.Node;
if (tn.Level == 0)
{
using (Graphics g = e.Graphics)
{
//g.Clear(this.BackColor); // 清空画布,完整重绘时才能使用
//g.SmoothingMode = SmoothingMode.HighQuality; // 高质量
//g.PixelOffsetMode = PixelOffsetMode.HighQuality; // 高像素偏移质量
//绘制分组的背景
//RenderBackgroundInternalRate(g,
// e.Bounds,
// GroupBgColor,
// GroupBgColor,
// Color.FromArgb(200, 255, 255, 255),
// 0.45f,
// true,
// 300);
int red = GroupBgColor.R;
int green = GroupBgColor.G;
int blue = GroupBgColor.B;
if (red < 127) red += 15; else red -= 15;
if (green < 127) green += 15; else green -= 15;
if (blue < 127) blue += 15; else blue -= 15;
var color = Color.FromArgb(red, green, blue);
RenderBackgroundSolid(g, e.Bounds, color, color, color, false);
//绘制展开按扭
//g.FillEllipse(new SolidBrush(ExpandButtonColor), ExpandButtonBounds(e.Bounds));
//g.DrawEllipse(new Pen(Color.LightGray), ExpandButtonBounds(e.Bounds));
//Point p1;
//Point p2;
//Point p3;
//if (tn.IsExpanded)
//{
// p1 = new Point(ExpandButtonBounds(e.Bounds).X + 3, ExpandButtonBounds(e.Bounds).Bottom - 4);
// p2 = new Point(ExpandButtonBounds(e.Bounds).X + (ExpandButtonSize.Width) / 2, ExpandButtonBounds(e.Bounds).Top + 5);
// p3 = new Point(ExpandButtonBounds(e.Bounds).Right - 3, ExpandButtonBounds(e.Bounds).Bottom - 4);
//}
//else
//{
// p1 = new Point(ExpandButtonBounds(e.Bounds).X + 3, ExpandButtonBounds(e.Bounds).Y + 4);
// p2 = new Point(ExpandButtonBounds(e.Bounds).X + (ExpandButtonSize.Width) / 2, ExpandButtonBounds(e.Bounds).Bottom - 5);
// p3 = new Point(ExpandButtonBounds(e.Bounds).Right - 3, ExpandButtonBounds(e.Bounds).Y + 4);
//}
//GraphicsPath gp = new GraphicsPath();
//gp.AddLine(p1, p2);
//gp.AddLine(p2, p3);
//g.DrawPath(new Pen(Color.FromArgb(255, 150, 0, 0), 2f), gp);
//绘制分组的文本
TextRenderer.DrawText(g, e.Node.Text, this.GroupFont, GroupTitleBounds(e.Bounds), this.GroupTitleColor,
TextFormatFlags.Left | TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis);
}
}
else if (tn.Level == 1)
{
//e.DrawDefault = true;
using (Graphics g = e.Graphics)
{
#region 小奶猫增加权限后,无法自动绘制TreeNode图标,经调试确认,增加此段代码 by ttzhao 2020.7.1
if (!dicNodeImageSelect.Keys.Contains(e.Node))
{
// 获取图标
if (Properties.Resources.ResourceManager.GetObject(e.Node.Text + "_select") != null)
{
var bitmap = (Bitmap)Properties.Resources.ResourceManager.GetObject(e.Node.Text + "_select");
dicNodeImageSelect[e.Node] = bitmap;
}
}
if (!dicNodeImage.Keys.Contains(e.Node))
{
// 获取图标
if (Properties.Resources.ResourceManager.GetObject(e.Node.Text) != null)
{
var bitmap = (Bitmap)Properties.Resources.ResourceManager.GetObject(e.Node.Text);
dicNodeImage[e.Node] = bitmap;
}
}
#endregion 小奶猫增加权限后,无法自动绘制TreeNode图标,经调试确认,增加此段代码 by ttzhao 2020.7.1
if (tn.IsSelected)
{
RenderBackgroundSolid(g, e.Bounds, ChildNodeSelectedBgColor, ChildNodeSelectedBgColor, ChildNodeSelectedBgColor, false);
//TextRenderer.DrawText(g, e.Node.Text, new Font(this.Font.FontFamily.Name, this.Font.Size, FontStyle.Underline), e.Bounds, OverForeColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
TextRenderer.DrawText(g, e.Node.Text, this.Font, ChildTitleBounds(e.Bounds), this.OverForeColor,
TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
// 绘制图标
if (dicNodeImageSelect.Keys.Contains(e.Node))
g.DrawImage(dicNodeImageSelect[e.Node], new Rectangle(e.Bounds.X + 30, e.Bounds.Y + 8, 16, 16));
else if (defaultNodeImageSelect != null)
g.DrawImage(defaultNodeImageSelect, new Rectangle(e.Bounds.X + 30, e.Bounds.Y + 8, 16, 16));
}
else
{
RenderBackgroundSolid(g, e.Bounds, GroupBgColor, GroupBgColor, GroupBgColor, false);
//TextRenderer.DrawText(g, e.Node.Text, this.Font, e.Bounds, this.ForeColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
TextRenderer.DrawText(g, e.Node.Text, this.Font, ChildTitleBounds(e.Bounds), this.ForeColor,
TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
// 绘制图标
if (dicNodeImage.Keys.Contains(e.Node))
g.DrawImage(dicNodeImage[e.Node], new Rectangle(e.Bounds.X + 30, e.Bounds.Y + 8, 16, 16));
else if (defaultNodeImage != null)
g.DrawImage(defaultNodeImage, new Rectangle(e.Bounds.X + 30, e.Bounds.Y + 8, 16, 16));
}
}
}
}
/// <summary>
/// 展开按扭区域 一级菜单后面的展开按钮
/// </summary>
/// <param name="childRect"></param>
/// <returns></returns>
private Rectangle ExpandButtonBounds(Rectangle childRect)
{
Rectangle lrect = new Rectangle(new Point(childRect.Right - ExpandButtonSize.Width * 3 / 2, (childRect.Height - ExpandButtonSize.Height) / 2 + childRect.Top), ExpandButtonSize);
return lrect;
}
/// <summary>
/// 取得分组标题绘制空间 一级菜单
/// </summary>
/// <param name="childRect"></param>
/// <returns></returns>
private Rectangle GroupTitleBounds(Rectangle childRect)
{
Rectangle lrect = childRect;
lrect.Width -= ExpandButtonSize.Width * 3 / 2 + 20;
//lrect.Offset(45, 0);
lrect.Offset(12, 0);
return lrect;
}
private Rectangle ChildTitleBounds(Rectangle rect)
{
Rectangle lrect = rect;
lrect.Width -= 50;
lrect.Offset(55, 0);
return lrect;
}
#endregion
#region //draw
internal void RenderBackgroundSolid(Graphics g, Rectangle rect, Color baseColor, Color borderColor, Color innerBorderColor, bool drawBorder)
{
if (drawBorder)
{
rect.Width--;
rect.Height--;
}
using (SolidBrush brush = new SolidBrush(baseColor))
{
g.FillRectangle(brush, rect);
}
if (drawBorder)
{
using (Pen pen = new Pen(borderColor))
{
g.DrawRectangle(pen, rect);
}
rect.Inflate(-1, -1);
using (Pen pen = new Pen(innerBorderColor))
{
g.DrawRectangle(pen, rect);
}
}
}
internal void RenderBackgroundInternal(Graphics g, Rectangle rect, Color baseColor, Color borderColor, Color innerBorderColor,
float basePosition, bool drawBorder, LinearGradientMode mode)
{
if (drawBorder)
{
rect.Width--;
rect.Height--;
}
using (LinearGradientBrush brush = new LinearGradientBrush(rect, Color.Transparent, Color.Transparent, mode))
{
Color[] colors = new Color[4];
colors[0] = GetColor(baseColor, 0, 35, 24, 9);
colors[1] = GetColor(baseColor, 0, 13, 8, 3);
colors[2] = baseColor;
colors[3] = GetColor(baseColor, 0, 68, 69, 54);
ColorBlend blend = new ColorBlend();
blend.Positions = new float[] { 0.0f, basePosition, basePosition + 0.05f, 1.0f };
blend.Colors = colors;
brush.InterpolationColors = blend;
g.FillRectangle(brush, rect);
}
if (baseColor.A > 80)
{
Rectangle rectTop = rect;
if (mode == LinearGradientMode.Vertical)
{
rectTop.Height = (int)(rectTop.Height * basePosition);
}
else
{
rectTop.Width = (int)(rect.Width * basePosition);
}
using (SolidBrush brushAlpha =
new SolidBrush(Color.FromArgb(80, 255, 255, 255)))
{
g.FillRectangle(brushAlpha, rectTop);
}
}
if (drawBorder)
{
using (Pen pen = new Pen(borderColor))
{
g.DrawRectangle(pen, rect);
}
rect.Inflate(-1, -1);
using (Pen pen = new Pen(innerBorderColor))
{
g.DrawRectangle(pen, rect);
}
}
}
internal void RenderBackgroundInternalRate(Graphics g, Rectangle rect, Color baseColor, Color borderColor, Color innerBorderColor,
float basePosition, bool drawBorder, float rate)
{
if (drawBorder)
{
rect.Width--;
rect.Height--;
}
using (LinearGradientBrush brush = new LinearGradientBrush(rect, Color.Transparent, Color.Transparent, rate))
{
Color[] colors = new Color[4];
colors[0] = GetColor(baseColor, 0, 35, 24, 9);
colors[1] = GetColor(baseColor, 0, 13, 8, 3);
colors[2] = baseColor;
colors[3] = GetColor(baseColor, 0, 68, 69, 54);
ColorBlend blend = new ColorBlend();
blend.Positions = new float[] { 0.0f, basePosition, basePosition + 0.05f, 1.0f };
blend.Colors = colors;
brush.InterpolationColors = blend;
g.FillRectangle(brush, rect);
}
if (baseColor.A > 80)
{
Rectangle rectTop = rect;
if (true/*mode == LinearGradientMode.Vertical*/)
{
rectTop.Height = (int)(rectTop.Height * basePosition);
}
else
{
rectTop.Width = (int)(rect.Width * basePosition);
}
using (SolidBrush brushAlpha =
new SolidBrush(Color.FromArgb(80, 255, 255, 255)))
{
g.FillRectangle(brushAlpha, rectTop);
}
}
if (drawBorder)
{
using (Pen pen = new Pen(borderColor))
{
g.DrawRectangle(pen, rect);
}
rect.Inflate(-1, -1);
using (Pen pen = new Pen(innerBorderColor))
{
g.DrawRectangle(pen, rect);
}
}
}
private Color GetColor(Color colorBase, int a, int r, int g, int b)
{
int a0 = colorBase.A;
int r0 = colorBase.R;
int g0 = colorBase.G;
int b0 = colorBase.B;
if (a + a0 > 255) { a = 255; } else { a = a + a0; }
if (r + r0 > 255) { r = 255; } else { r = r + r0; }
if (g + g0 > 255) { g = 255; } else { g = g + g0; }
if (b + b0 > 255) { b = 255; } else { b = b + b0; }
return Color.FromArgb(a, r, g, b);
}
private Color GetColor2(Color colorBase, int a, int r, int g, int b)
{
int a0 = colorBase.A;
int r0 = colorBase.R;
int g0 = colorBase.G;
int b0 = colorBase.B;
if (a + a0 > 255) { a = 255; } else { a = a + a0; }
if (r0 - r < 0) { r = 0; } else { r = r0 - r; }
if (g0 - g < 0) { g = 0; } else { g = g0 - g; }
if (b0 - b < 0) { b = 0; } else { b = b0 - b; }
return Color.FromArgb(a, r, g, b);
}
#endregion
public static int LOWORD(int value)
{
return value & 0xFFFF;
}
public static int HIWORD(int value)
{
return value >> 16;
}
public void ExpandGroup(string groupName)
{
var node = this.AllNodes.FirstOrDefault(n => n.Name == groupName);
if (node == null)
return;
BeginUpdate();
if (!this.Nodes.Contains(node))
this.Nodes.Insert(0, node);
node.Expand();
EndUpdate();
}
}
}