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; } } }