using System;
|
using System.Collections.Generic;
|
using System.ComponentModel;
|
using System.Drawing;
|
using System.Data;
|
using System.Text;
|
using System.Linq;
|
using System.Windows.Forms;
|
using System.Drawing.Drawing2D;
|
using System.Drawing.Imaging;
|
|
namespace IStation.WinFormUI
|
{
|
/// <summary>
|
/// 自定义TreeList控件
|
/// </summary>
|
public partial class CTreeList : TreeView
|
{
|
public CTreeList()
|
{
|
InitializeComponent();
|
this.ItemHeight = 200;
|
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
|
this.DrawMode = TreeViewDrawMode.OwnerDrawAll;
|
this.ShowLines = true;
|
|
}
|
|
#region 属性
|
|
private bool _isDrawBorder = false;
|
/// <summary>
|
/// 是否绘制边框
|
/// </summary>
|
[Description("是否绘制边框"), Category("XOProperty")]
|
public bool IsDrawBorder
|
{
|
get
|
{
|
return _isDrawBorder;
|
}
|
set
|
{
|
if (_isDrawBorder != value)
|
{
|
_isDrawBorder = value;
|
this.Invalidate();
|
}
|
}
|
}
|
|
|
private Color _borderColor = Color.Transparent;
|
/// <summary>
|
/// 绘制节点边框的颜色
|
/// </summary>
|
[Description("绘制节点边框的颜色"), Category("XOProperty")]
|
public Color BorderColor
|
{
|
get
|
{
|
return _borderColor;
|
}
|
set
|
{
|
if (_borderColor != value)
|
{
|
_borderColor = value;
|
this.Invalidate();
|
}
|
}
|
}
|
|
|
private Color _nodeBgColor = Color.FromArgb(242, 242, 242);
|
/// <summary>
|
/// 绘制Node的背景色
|
/// </summary>
|
[Description("绘制Node的背景色"), Category("XOProperty")]
|
public Color NodeBgColor
|
{
|
get
|
{
|
return _nodeBgColor;
|
}
|
set
|
{
|
if (_nodeBgColor != value)
|
{
|
_nodeBgColor = value;
|
this.Invalidate();
|
|
}
|
}
|
}
|
|
private Color _textColor = Color.White;
|
|
/// <summary>
|
/// 绘制文本的颜色
|
/// </summary>
|
[Description("绘制Text的背景色"), Category("XOProperty")]
|
public Color TextColor
|
{
|
get
|
{
|
return _textColor;
|
}
|
set
|
{
|
if (_textColor != value)
|
{
|
_textColor = value;
|
this.Invalidate();
|
|
}
|
}
|
}
|
|
private Color _selectedBorderColor = Color.Transparent;
|
/// <summary>
|
/// 绘制选中节点边框的颜色
|
/// </summary>
|
[Description("绘制选中节点边框的颜色"), Category("XOProperty")]
|
public Color SelectedBorderColor
|
{
|
get
|
{
|
return _selectedBorderColor;
|
}
|
set
|
{
|
if (_selectedBorderColor != value)
|
{
|
_selectedBorderColor = value;
|
this.Invalidate();
|
}
|
}
|
}
|
|
|
private Color _selectedTextColor = Color.White;
|
/// <summary>
|
/// 选中Node文字颜色
|
/// </summary>
|
[Description("选中Node文字颜色"), Category("XOProperty")]
|
public Color SelectedTextColor
|
{
|
get
|
{
|
return _selectedTextColor;
|
}
|
set
|
{
|
if (_selectedTextColor != value)
|
{
|
_selectedTextColor = value;
|
this.Invalidate();
|
}
|
}
|
}
|
|
|
private Color _selectedBgColor = Color.FromArgb(129, 211, 248);
|
/// <summary>
|
/// 选中Node的背景颜色
|
/// </summary>
|
[Description("选中Node背景颜色"), Category("XOProperty")]
|
public Color SelectedBgColor
|
{
|
get
|
{
|
return _selectedBgColor;
|
}
|
set
|
{
|
if (_selectedBgColor != value)
|
{
|
_selectedBgColor = value;
|
this.Invalidate();
|
}
|
}
|
}
|
|
|
private int _nodelevelWidth = 30;
|
/// <summary>
|
/// 节点缩进宽度
|
/// </summary>
|
[Description("节点缩进宽度"), Category("XOProperty")]
|
public int ChildNodeLevelWidth
|
{
|
get
|
{
|
return _nodelevelWidth;
|
}
|
set
|
{
|
if (_nodelevelWidth != value)
|
{
|
_nodelevelWidth = value;
|
this.Invalidate();
|
}
|
}
|
}
|
|
private int _spaceText = 10;
|
/// <summary>
|
/// 图片与文字的间距
|
/// </summary>
|
[Description("图片与文字的间距"), Category("XOProperty")]
|
public int SpaceText
|
{
|
get
|
{
|
return _spaceText;
|
}
|
set
|
{
|
if (_spaceText != value)
|
{
|
_spaceText = value;
|
this.Invalidate();
|
}
|
}
|
}
|
|
|
private int _leftSpaceImg = 10;
|
/// <summary>
|
/// 图片与左边框的间距
|
/// </summary>
|
[Description("图片与文字的间距"), Category("XOProperty")]
|
public int LeftSpaceImg
|
{
|
get
|
{
|
return _leftSpaceImg;
|
}
|
set
|
{
|
if (_leftSpaceImg != value)
|
{
|
_leftSpaceImg = value;
|
this.Invalidate();
|
}
|
}
|
}
|
|
|
private int _leftSpace = 30;
|
/// <summary>
|
/// 左边距
|
/// </summary>
|
[Description("左边距"), Category("XOProperty")]
|
public int LeftSpace
|
{
|
get
|
{
|
return _leftSpace;
|
}
|
set
|
{
|
if (_leftSpace != value)
|
{
|
_leftSpace = value;
|
this.Invalidate();
|
}
|
}
|
}
|
|
private int _drawNodeHeight = 180;
|
/// <summary>
|
/// 绘制的节点的高度
|
/// </summary>
|
[Description("绘制的节点的高度"), Category("XOProperty")]
|
public int DrawNodeHeight
|
{
|
get
|
{
|
return _drawNodeHeight;
|
}
|
set
|
{
|
if (_drawNodeHeight > ItemHeight)
|
_drawNodeHeight = ItemHeight;
|
if (_drawNodeHeight != value)
|
{
|
_drawNodeHeight = value;
|
this.Invalidate();
|
}
|
}
|
}
|
|
|
private Image _butExpandImage = null;
|
/// <summary>
|
/// 下拉按钮图片
|
/// </summary>
|
[Description("下拉按钮图片"), Category("XOProperty")]
|
public Image ButImage
|
{
|
get
|
{
|
return _butExpandImage;
|
}
|
set
|
{
|
if (_butExpandImage != value)
|
{
|
_butExpandImage = value;
|
this.Invalidate();
|
}
|
}
|
}
|
|
#endregion
|
|
private List<CTreeNode> _treeNodeList;
|
|
/// <summary>
|
/// 节点改变事件
|
/// </summary>
|
public event Action<CTreeNode> FocusedNodeChangedEvent = null;
|
|
//设置属性
|
public void SetNodes(List<CTreeNode> tree)
|
{
|
if (tree == null||tree.Count<1)
|
return;
|
_treeNodeList = tree;
|
_treeNodeList.ForEach(node =>
|
{
|
var rootNode = new System.Windows.Forms.TreeNode();
|
rootNode.Text = node.Caption;
|
rootNode.Tag = node;
|
this.Nodes.Add(rootNode);
|
});
|
}
|
|
private Size ExpandButtonSize = new Size(16, 16);
|
|
/// <summary>
|
/// 自定义绘制节点
|
/// </summary>
|
/// <param name="e"></param>
|
private void DrawNodeItem(DrawTreeNodeEventArgs e)
|
{
|
System.Windows.Forms.TreeNode node = e.Node;
|
var model = node.Tag as CTreeNode;
|
if (model == null)
|
return;
|
using (Graphics g = e.Graphics)
|
{
|
Rectangle rect;
|
var am_height = this.DrawNodeHeightAugment();
|
rect = new Rectangle(e.Bounds.X, e.Bounds.Y + am_height, (int)(this.Width * model.DrawNodeWidthRatio), DrawNodeHeight);
|
|
var path = BuildGraphicsPath(e.Bounds.Location, (int)(this.Width * model.DrawNodeWidthRatio), DrawNodeHeight);
|
//绘制分组的背景
|
RenderBackgroundInternalRate(node, g, path);
|
|
Point p_cap = new Point(rect.X + LeftSpace, rect.Y + rect.Height / 2);
|
if (node.IsSelected)
|
{
|
TextRenderer.DrawText(g, model.Caption, new Font(this.Font.FontFamily.Name, this.Font.Size, FontStyle.Regular), p_cap, this.SelectedTextColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
|
}
|
else
|
{
|
TextRenderer.DrawText(g, model.Caption, new Font(this.Font.FontFamily.Name, this.Font.Size, FontStyle.Regular), p_cap, this.TextColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
|
}
|
|
Point p_value = new Point(rect.Width- (int)(rect.Width * 0.2), rect.Y+rect.Height/2);
|
|
/*if (node.IsSelected)
|
{
|
TextRenderer.DrawText(g, model.Range, new Font(this.Font.FontFamily.Name, this.Font.Size, FontStyle.Regular), p_value, this.SelectedTextColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
|
}
|
else
|
{
|
TextRenderer.DrawText(g, model.Range, new Font(this.Font.FontFamily.Name, this.Font.Size, FontStyle.Regular), p_value, this.TextColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
|
}*/
|
}
|
}
|
|
#region override
|
protected override void OnDrawNode(DrawTreeNodeEventArgs 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));
|
System.Windows.Forms.TreeNode tn = this.GetNodeAt(point);
|
if (tn == null)
|
{
|
base.WndProc(ref m);
|
return;
|
}
|
if (IsChlckNode(tn, point))
|
{
|
this.SelectedNode = tn;
|
}
|
|
}
|
base.WndProc(ref m);
|
|
}
|
#endregion
|
|
//判断鼠标是否点击在绘制的节点上
|
private bool IsChlckNode(System.Windows.Forms.TreeNode node, Point p)
|
{
|
var model = node.Tag as CTreeNode;
|
var am_height = this.DrawNodeHeightAugment();
|
var rect = new Rectangle(1, node.Bounds.Y + am_height, this.Width, DrawNodeHeight);
|
var a = node.TreeView.Nodes[0];
|
return rect.Contains(p);
|
}
|
|
//绘制多边形
|
private GraphicsPath BuildGraphicsPath(Point basePoint, float width, float height)
|
{
|
GraphicsPath path = new GraphicsPath();
|
path.AddLine(basePoint.X, basePoint.Y, basePoint.X + width, basePoint.Y);
|
path.AddLine(basePoint.X + width, basePoint.Y, basePoint.X + width + height/2, basePoint.Y + height/2);
|
path.AddLine(basePoint.X + width + height / 2, basePoint.Y + height / 2, basePoint.X + width , basePoint.Y + height );
|
path.AddLine(basePoint.X + width , basePoint.Y + height , basePoint.X , basePoint.Y+height );
|
path.AddLine(basePoint.X , basePoint.Y + height, basePoint.X, basePoint.Y );
|
return path;
|
}
|
|
//绘制节点
|
internal void RenderBackgroundInternalRate(System.Windows.Forms.TreeNode node, Graphics g, GraphicsPath rect)
|
{
|
var model = node.Tag as CTreeNode;
|
|
if (node.IsSelected)
|
{
|
using (var brushAlpha = new SolidBrush(SelectedBgColor))
|
{
|
g.FillPath(brushAlpha, rect); ;
|
}
|
}
|
else
|
{
|
using (var brushAlpha = new SolidBrush(model.Color))
|
{
|
g.FillPath(brushAlpha, rect);
|
}
|
}
|
|
}
|
|
//绘制节点高度的增量
|
private int DrawNodeHeightAugment()
|
{
|
if (DrawNodeHeight >= ItemHeight)
|
return 0;
|
return (ItemHeight - DrawNodeHeight) / 2;
|
}
|
|
private static int LOWORD(int value)
|
{
|
return value & 0xFFFF;
|
}
|
|
private static int HIWORD(int value)
|
{
|
return value >> 16;
|
}
|
|
private CTreeNode _currentClickNode;
|
|
private void CTreeList_AfterSelect(object sender, TreeViewEventArgs e)
|
{
|
if (e.Node == null)
|
return;
|
var nodeData = e.Node.Tag as CTreeNode;
|
if (nodeData == null)
|
return;
|
if (nodeData.IsReadOnly)
|
return;
|
_currentClickNode = nodeData;
|
if (FocusedNodeChangedEvent != null)
|
FocusedNodeChangedEvent.Invoke(nodeData);
|
}
|
|
public CTreeNode GetFocusedRow()
|
{
|
return _currentClickNode;
|
}
|
|
/// <summary>
|
/// 自定义创建图片的副本(若PixelFormat为索引像素格式会抛异常))
|
/// </summary>
|
/// <param name="img"></param>
|
/// <param name="format">默认Format32bppArgb</param>
|
/// <returns></returns>
|
private static Image CloneC(Image img, PixelFormat format = PixelFormat.Format32bppArgb)
|
{
|
var bmp = new Bitmap(img.Width, img.Height, format);
|
using (var g = Graphics.FromImage(bmp))
|
{
|
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
|
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
|
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
|
g.DrawImage(img, new Rectangle(0, 0, bmp.Width, bmp.Height));
|
}
|
return bmp;
|
}
|
}
|
}
|