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
{
///
/// 自定义TreeList控件
///
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;
///
/// 是否绘制边框
///
[Description("是否绘制边框"), Category("XOProperty")]
public bool IsDrawBorder
{
get
{
return _isDrawBorder;
}
set
{
if (_isDrawBorder != value)
{
_isDrawBorder = value;
this.Invalidate();
}
}
}
private Color _borderColor = Color.Transparent;
///
/// 绘制节点边框的颜色
///
[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);
///
/// 绘制Node的背景色
///
[Description("绘制Node的背景色"), Category("XOProperty")]
public Color NodeBgColor
{
get
{
return _nodeBgColor;
}
set
{
if (_nodeBgColor != value)
{
_nodeBgColor = value;
this.Invalidate();
}
}
}
private Color _textColor = Color.White;
///
/// 绘制文本的颜色
///
[Description("绘制Text的背景色"), Category("XOProperty")]
public Color TextColor
{
get
{
return _textColor;
}
set
{
if (_textColor != value)
{
_textColor = value;
this.Invalidate();
}
}
}
private Color _selectedBorderColor = Color.Transparent;
///
/// 绘制选中节点边框的颜色
///
[Description("绘制选中节点边框的颜色"), Category("XOProperty")]
public Color SelectedBorderColor
{
get
{
return _selectedBorderColor;
}
set
{
if (_selectedBorderColor != value)
{
_selectedBorderColor = value;
this.Invalidate();
}
}
}
private Color _selectedTextColor = Color.White;
///
/// 选中Node文字颜色
///
[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);
///
/// 选中Node的背景颜色
///
[Description("选中Node背景颜色"), Category("XOProperty")]
public Color SelectedBgColor
{
get
{
return _selectedBgColor;
}
set
{
if (_selectedBgColor != value)
{
_selectedBgColor = value;
this.Invalidate();
}
}
}
private int _nodelevelWidth = 30;
///
/// 节点缩进宽度
///
[Description("节点缩进宽度"), Category("XOProperty")]
public int ChildNodeLevelWidth
{
get
{
return _nodelevelWidth;
}
set
{
if (_nodelevelWidth != value)
{
_nodelevelWidth = value;
this.Invalidate();
}
}
}
private int _spaceText = 10;
///
/// 图片与文字的间距
///
[Description("图片与文字的间距"), Category("XOProperty")]
public int SpaceText
{
get
{
return _spaceText;
}
set
{
if (_spaceText != value)
{
_spaceText = value;
this.Invalidate();
}
}
}
private int _leftSpaceImg = 10;
///
/// 图片与左边框的间距
///
[Description("图片与文字的间距"), Category("XOProperty")]
public int LeftSpaceImg
{
get
{
return _leftSpaceImg;
}
set
{
if (_leftSpaceImg != value)
{
_leftSpaceImg = value;
this.Invalidate();
}
}
}
private int _leftSpace = 30;
///
/// 左边距
///
[Description("左边距"), Category("XOProperty")]
public int LeftSpace
{
get
{
return _leftSpace;
}
set
{
if (_leftSpace != value)
{
_leftSpace = value;
this.Invalidate();
}
}
}
private int _drawNodeHeight = 180;
///
/// 绘制的节点的高度
///
[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;
///
/// 下拉按钮图片
///
[Description("下拉按钮图片"), Category("XOProperty")]
public Image ButImage
{
get
{
return _butExpandImage;
}
set
{
if (_butExpandImage != value)
{
_butExpandImage = value;
this.Invalidate();
}
}
}
#endregion
private List _treeNodeList;
///
/// 节点改变事件
///
public event Action FocusedNodeChangedEvent = null;
//设置属性
public void SetNodes(List 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);
///
/// 自定义绘制节点
///
///
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;
}
///
/// 自定义创建图片的副本(若PixelFormat为索引像素格式会抛异常))
///
///
/// 默认Format32bppArgb
///
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;
}
}
}