(九)c#Winform自定义控件-树-HZHControls
官网
前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
如果觉得写的还行,请点个 star 支持一下吧
目录
https://www.cnblogs.com/bfyx/p/11364884.html
准备工作
对原始树控件treeview进行扩展以更改样式
先了解一下我们需要哪些功能,控件ain可以更改整好颜色,行高,选中效果,分割线等
开始
添加组件,命名TreeViewEx 继承TreeView
先看下属性
1 private const int WS_VSCROLL = 2097152; 2 3 private const int GWL_STYLE = -16; 4 5 private Dictionary<string, string> _lstTips = new Dictionary<string, string>(); 6 7 private Font _tipFont = new Font("Arial Unicode MS", 12f); 8 9 private Image _tipImage = Resources.tips; 10 11 private bool _isShowTip = false; 12 13 private bool _isShowByCustomModel = true; 14 15 private int _nodeHeight = 50; 16 17 private Image _nodeDownPic = Resources.list_add; 18 19 private Image _nodeUpPic = Resources.list_subtract; 20 21 private Color _nodeBackgroundColor = Color.FromArgb(61, 60, 66); 22 23 private Color _nodeForeColor = Color.White; 24 25 private bool _nodeIsShowSplitLine = false; 26 27 private Color _nodeSplitLineColor = Color.FromArgb(54, 53, 58); 28 29 private Color m_nodeSelectedColor = Color.FromArgb(255, 121, 74); 30 31 private Color m_nodeSelectedForeColor = Color.White; 32 33 private bool _parentNodeCanSelect = true; 34 35 private SizeF treeFontSize = SizeF.Empty; 36 37 private bool blnHasVBar = false; 38 39 public Dictionary<string, string> LstTips 40 { 41 get 42 { 43 return this._lstTips; 44 } 45 set 46 { 47 this._lstTips = value; 48 } 49 } 50 51 [Category("自定义属性"), Description("角标文字字体")] 52 public Font TipFont 53 { 54 get 55 { 56 return this._tipFont; 57 } 58 set 59 { 60 this._tipFont = value; 61 } 62 } 63 64 [Category("自定义属性"), Description("是否显示角标")] 65 public Image TipImage 66 { 67 get 68 { 69 return this._tipImage; 70 } 71 set 72 { 73 this._tipImage = value; 74 } 75 } 76 77 [Category("自定义属性"), Description("是否显示角标")] 78 public bool IsShowTip 79 { 80 get 81 { 82 return this._isShowTip; 83 } 84 set 85 { 86 this._isShowTip = value; 87 } 88 } 89 90 [Category("自定义属性"), Description("使用自定义模式")] 91 public bool IsShowByCustomModel 92 { 93 get 94 { 95 return this._isShowByCustomModel; 96 } 97 set 98 { 99 this._isShowByCustomModel = value; 100 } 101 } 102 103 [Category("自定义属性"), Description("节点高度(IsShowByCustomModel=true时生效)")] 104 public int NodeHeight 105 { 106 get 107 { 108 return this._nodeHeight; 109 } 110 set 111 { 112 this._nodeHeight = value; 113 base.ItemHeight = value; 114 } 115 } 116 117 [Category("自定义属性"), Description("下翻图标(IsShowByCustomModel=true时生效)")] 118 public Image NodeDownPic 119 { 120 get 121 { 122 return this._nodeDownPic; 123 } 124 set 125 { 126 this._nodeDownPic = value; 127 } 128 } 129 130 [Category("自定义属性"), Description("上翻图标(IsShowByCustomModel=true时生效)")] 131 public Image NodeUpPic 132 { 133 get 134 { 135 return this._nodeUpPic; 136 } 137 set 138 { 139 this._nodeUpPic = value; 140 } 141 } 142 143 [Category("自定义属性"), Description("节点背景颜色(IsShowByCustomModel=true时生效)")] 144 public Color NodeBackgroundColor 145 { 146 get 147 { 148 return this._nodeBackgroundColor; 149 } 150 set 151 { 152 this._nodeBackgroundColor = value; 153 } 154 } 155 156 [Category("自定义属性"), Description("节点字体颜色(IsShowByCustomModel=true时生效)")] 157 public Color NodeForeColor 158 { 159 get 160 { 161 return this._nodeForeColor; 162 } 163 set 164 { 165 this._nodeForeColor = value; 166 } 167 } 168 169 [Category("自定义属性"), Description("节点是否显示分割线(IsShowByCustomModel=true时生效)")] 170 public bool NodeIsShowSplitLine 171 { 172 get 173 { 174 return this._nodeIsShowSplitLine; 175 } 176 set 177 { 178 this._nodeIsShowSplitLine = value; 179 } 180 } 181 182 [Category("自定义属性"), Description("节点分割线颜色(IsShowByCustomModel=true时生效)")] 183 public Color NodeSplitLineColor 184 { 185 get 186 { 187 return this._nodeSplitLineColor; 188 } 189 set 190 { 191 this._nodeSplitLineColor = value; 192 } 193 } 194 195 [Category("自定义属性"), Description("选中节点背景颜色(IsShowByCustomModel=true时生效)")] 196 public Color NodeSelectedColor 197 { 198 get 199 { 200 return this.m_nodeSelectedColor; 201 } 202 set 203 { 204 this.m_nodeSelectedColor = value; 205 } 206 } 207 208 [Category("自定义属性"), Description("选中节点字体颜色(IsShowByCustomModel=true时生效)")] 209 public Color NodeSelectedForeColor 210 { 211 get 212 { 213 return this.m_nodeSelectedForeColor; 214 } 215 set 216 { 217 this.m_nodeSelectedForeColor = value; 218 } 219 } 220 221 [Category("自定义属性"), Description("父节点是否可选中")] 222 public bool ParentNodeCanSelect 223 { 224 get 225 { 226 return this._parentNodeCanSelect; 227 } 228 set 229 { 230 this._parentNodeCanSelect = value; 231 } 232 }
样式的更改主要通过节点的重绘,我们使用DrawNode事件来完成
1 base.DrawNode += new DrawTreeNodeEventHandler(this.treeview_DrawNode); 2 3 private void treeview_DrawNode(object sender, DrawTreeNodeEventArgs e) 4 { 5 try 6 { 7 if (e.Node == null || !this._isShowByCustomModel || (e.Node.Bounds.Width <= 0 && e.Node.Bounds.Height <= 0 && e.Node.Bounds.X <= 0 && e.Node.Bounds.Y <= 0)) 8 { 9 e.DrawDefault = true; 10 } 11 else 12 { 13 if (base.Nodes.IndexOf(e.Node) == 0) 14 { 15 this.blnHasVBar = this.IsVerticalScrollBarVisible(); 16 } 17 Font font = e.Node.NodeFont; 18 if (font == null) 19 { 20 font = ((TreeView)sender).Font; 21 } 22 if (this.treeFontSize == SizeF.Empty) 23 { 24 this.treeFontSize = this.GetFontSize(font, e.Graphics); 25 } 26 bool flag = false; 27 int num = 0; 28 if (base.ImageList != null && base.ImageList.Images.Count > 0 && e.Node.ImageIndex >= 0 && e.Node.ImageIndex < base.ImageList.Images.Count) 29 { 30 flag = true; 31 num = (e.Bounds.Height - base.ImageList.ImageSize.Height) / 2; 32 } 33 if ((e.State == TreeNodeStates.Selected || e.State == TreeNodeStates.Focused || e.State == (TreeNodeStates.Focused | TreeNodeStates.Selected)) && (this._parentNodeCanSelect || e.Node.Nodes.Count <= 0)) 34 { 35 e.Graphics.FillRectangle(new SolidBrush(this.m_nodeSelectedColor), new Rectangle(new Point(0, e.Node.Bounds.Y), new Size(base.Width, e.Node.Bounds.Height))); 36 e.Graphics.DrawString(e.Node.Text, font, new SolidBrush(this.m_nodeSelectedForeColor), (float)e.Bounds.X, (float)e.Bounds.Y + ((float)this._nodeHeight - this.treeFontSize.Height) / 2f); 37 } 38 else 39 { 40 e.Graphics.FillRectangle(new SolidBrush(this._nodeBackgroundColor), new Rectangle(new Point(0, e.Node.Bounds.Y), new Size(base.Width, e.Node.Bounds.Height))); 41 e.Graphics.DrawString(e.Node.Text, font, new SolidBrush(this._nodeForeColor), (float)e.Bounds.X, (float)e.Bounds.Y + ((float)this._nodeHeight - this.treeFontSize.Height) / 2f); 42 } 43 if (flag) 44 { 45 int num2 = e.Bounds.X - num - base.ImageList.ImageSize.Width; 46 if (num2 < 0) 47 { 48 num2 = 3; 49 } 50 e.Graphics.DrawImage(base.ImageList.Images[e.Node.ImageIndex], new Rectangle(new Point(num2, e.Bounds.Y + num), base.ImageList.ImageSize)); 51 } 52 if (this._nodeIsShowSplitLine) 53 { 54 e.Graphics.DrawLine(new Pen(this._nodeSplitLineColor, 1f), new Point(0, e.Bounds.Y + this._nodeHeight - 1), new Point(base.Width, e.Bounds.Y + this._nodeHeight - 1)); 55 } 56 bool flag2 = false; 57 if (e.Node.Nodes.Count > 0) 58 { 59 if (e.Node.IsExpanded && this._nodeUpPic != null) 60 { 61 e.Graphics.DrawImage(this._nodeUpPic, new Rectangle(base.Width - (this.blnHasVBar ? 50 : 30), e.Bounds.Y + (this._nodeHeight - 20) / 2, 20, 20)); 62 } 63 else if (this._nodeDownPic != null) 64 { 65 e.Graphics.DrawImage(this._nodeDownPic, new Rectangle(base.Width - (this.blnHasVBar ? 50 : 30), e.Bounds.Y + (this._nodeHeight - 20) / 2, 20, 20)); 66 } 67 flag2 = true; 68 } 69 if (this._isShowTip && this._lstTips.ContainsKey(e.Node.Name) && !string.IsNullOrWhiteSpace(this._lstTips[e.Node.Name])) 70 { 71 int num3 = base.Width - (this.blnHasVBar ? 50 : 30) - (flag2 ? 20 : 0); 72 int num4 = e.Bounds.Y + (this._nodeHeight - 20) / 2; 73 e.Graphics.DrawImage(this._tipImage, new Rectangle(num3, num4, 20, 20)); 74 SizeF sizeF = e.Graphics.MeasureString(this._lstTips[e.Node.Name], this._tipFont, 100, StringFormat.GenericTypographic); 75 e.Graphics.DrawString(this._lstTips[e.Node.Name], this._tipFont, new SolidBrush(Color.White), (float)(num3 + 10) - sizeF.Width / 2f - 3f, (float)(num4 + 10) - sizeF.Height / 2f); 76 } 77 } 78 } 79 catch (Exception ex) 80 { 81 throw ex; 82 } 83 } 84 85 private SizeF GetFontSize(Font font, Graphics g = null) 86 { 87 SizeF result; 88 try 89 { 90 bool flag = false; 91 if (g == null) 92 { 93 g = base.CreateGraphics(); 94 flag = true; 95 } 96 SizeF sizeF = g.MeasureString("a", font, 100, StringFormat.GenericTypographic); 97 if (flag) 98 { 99 g.Dispose(); 100 } 101 result = sizeF; 102 } 103 catch (Exception ex) 104 { 105 throw ex; 106 } 107 return result; 108 } 109 110 [DllImport("user32", CharSet = CharSet.Auto)] 111 private static extern int GetWindowLong(IntPtr hwnd, int nIndex); 112 113 private bool IsVerticalScrollBarVisible() 114 { 115 return base.IsHandleCreated && (TreeViewEx.GetWindowLong(base.Handle, -16) & 2097152) != 0; 116 }
我们还需要对选中节点时做一些处理
1 private void TreeViewEx_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) 2 { 3 try 4 { 5 if (e.Node != null) 6 { 7 if (e.Node.Nodes.Count > 0) 8 { 9 if (e.Node.IsExpanded) 10 { 11 e.Node.Collapse(); 12 } 13 else 14 { 15 e.Node.Expand(); 16 } 17 } 18 if (base.SelectedNode != null) 19 { 20 if (base.SelectedNode == e.Node && e.Node.IsExpanded) 21 { 22 if (!this._parentNodeCanSelect) 23 { 24 if (e.Node.Nodes.Count > 0) 25 { 26 base.SelectedNode = e.Node.Nodes[0]; 27 } 28 } 29 } 30 } 31 } 32 } 33 catch (Exception ex) 34 { 35 throw ex; 36 } 37 }
选中后也需要根据属性做相应的操作
1 private void TreeViewEx_AfterSelect(object sender, TreeViewEventArgs e) 2 { 3 try 4 { 5 if (e.Node != null) 6 { 7 if (!this._parentNodeCanSelect) 8 { 9 if (e.Node.Nodes.Count > 0) 10 { 11 e.Node.Expand(); 12 base.SelectedNode = e.Node.Nodes[0]; 13 } 14 } 15 } 16 } 17 catch (Exception ex) 18 { 19 throw ex; 20 } 21 }
主要的东西就这些了,我们看下完成的代码吧
1 // 版权所有 黄正辉 交流群:568015492 QQ:623128629 2 // 文件名称:TreeViewEx.cs 3 // 创建日期:2019-08-15 16:00:55 4 // 功能描述:TreeView 5 // 项目地址:https://gitee.com/kwwwvagaa/net_winform_custom_control 6 7 using System; 8 using System.Collections.Generic; 9 using System.ComponentModel; 10 using System.Diagnostics; 11 using System.Drawing; 12 using System.Linq; 13 using System.Runtime.InteropServices; 14 using System.Text; 15 using System.Windows.Forms; 16 using HZH_Controls.Properties; 17 18 namespace HZH_Controls.Controls 19 { 20 public partial class TreeViewEx : TreeView 21 { 22 23 private const int WS_VSCROLL = 2097152; 24 25 private const int GWL_STYLE = -16; 26 27 private Dictionary<string, string> _lstTips = new Dictionary<string, string>(); 28 29 private Font _tipFont = new Font("Arial Unicode MS", 12f); 30 31 private Image _tipImage = Resources.tips; 32 33 private bool _isShowTip = false; 34 35 private bool _isShowByCustomModel = true; 36 37 private int _nodeHeight = 50; 38 39 private Image _nodeDownPic = Resources.list_add; 40 41 private Image _nodeUpPic = Resources.list_subtract; 42 43 private Color _nodeBackgroundColor = Color.FromArgb(61, 60, 66); 44 45 private Color _nodeForeColor = Color.White; 46 47 private bool _nodeIsShowSplitLine = false; 48 49 private Color _nodeSplitLineColor = Color.FromArgb(54, 53, 58); 50 51 private Color m_nodeSelectedColor = Color.FromArgb(255, 121, 74); 52 53 private Color m_nodeSelectedForeColor = Color.White; 54 55 private bool _parentNodeCanSelect = true; 56 57 private SizeF treeFontSize = SizeF.Empty; 58 59 private bool blnHasVBar = false; 60 61 public Dictionary<string, string> LstTips 62 { 63 get 64 { 65 return this._lstTips; 66 } 67 set 68 { 69 this._lstTips = value; 70 } 71 } 72 73 [Category("自定义属性"), Description("角标文字字体")] 74 public Font TipFont 75 { 76 get 77 { 78 return this._tipFont; 79 } 80 set 81 { 82 this._tipFont = value; 83 } 84 } 85 86 [Category("自定义属性"), Description("是否显示角标")] 87 public Image TipImage 88 { 89 get 90 { 91 return this._tipImage; 92 } 93 set 94 { 95 this._tipImage = value; 96 } 97 } 98 99 [Category("自定义属性"), Description("是否显示角标")] 100 public bool IsShowTip 101 { 102 get 103 { 104 return this._isShowTip; 105 } 106 set 107 { 108 this._isShowTip = value; 109 } 110 } 111 112 [Category("自定义属性"), Description("使用自定义模式")] 113 public bool IsShowByCustomModel 114 { 115 get 116 { 117 return this._isShowByCustomModel; 118 } 119 set 120 { 121 this._isShowByCustomModel = value; 122 } 123 } 124 125 [Category("自定义属性"), Description("节点高度(IsShowByCustomModel=true时生效)")] 126 public int NodeHeight 127 { 128 get 129 { 130 return this._nodeHeight; 131 } 132 set 133 { 134 this._nodeHeight = value; 135 base.ItemHeight = value; 136 } 137 } 138 139 [Category("自定义属性"), Description("下翻图标(IsShowByCustomModel=true时生效)")] 140 public Image NodeDownPic 141 { 142 get 143 { 144 return this._nodeDownPic; 145 } 146 set 147 { 148 this._nodeDownPic = value; 149 } 150 } 151 152 [Category("自定义属性"), Description("上翻图标(IsShowByCustomModel=true时生效)")] 153 public Image NodeUpPic 154 { 155 get 156 { 157 return this._nodeUpPic; 158 } 159 set 160 { 161 this._nodeUpPic = value; 162 } 163 } 164 165 [Category("自定义属性"), Description("节点背景颜色(IsShowByCustomModel=true时生效)")] 166 public Color NodeBackgroundColor 167 { 168 get 169 { 170 return this._nodeBackgroundColor; 171 } 172 set 173 { 174 this._nodeBackgroundColor = value; 175 } 176 } 177 178 [Category("自定义属性"), Description("节点字体颜色(IsShowByCustomModel=true时生效)")] 179 public Color NodeForeColor 180 { 181 get 182 { 183 return this._nodeForeColor; 184 } 185 set 186 { 187 this._nodeForeColor = value; 188 } 189 } 190 191 [Category("自定义属性"), Description("节点是否显示分割线(IsShowByCustomModel=true时生效)")] 192 public bool NodeIsShowSplitLine 193 { 194 get 195 { 196 return this._nodeIsShowSplitLine; 197 } 198 set 199 { 200 this._nodeIsShowSplitLine = value; 201 } 202 } 203 204 [Category("自定义属性"), Description("节点分割线颜色(IsShowByCustomModel=true时生效)")] 205 public Color NodeSplitLineColor 206 { 207 get 208 { 209 return this._nodeSplitLineColor; 210 } 211 set 212 { 213 this._nodeSplitLineColor = value; 214 } 215 } 216 217 [Category("自定义属性"), Description("选中节点背景颜色(IsShowByCustomModel=true时生效)")] 218 public Color NodeSelectedColor 219 { 220 get 221 { 222 return this.m_nodeSelectedColor; 223 } 224 set 225 { 226 this.m_nodeSelectedColor = value; 227 } 228 } 229 230 [Category("自定义属性"), Description("选中节点字体颜色(IsShowByCustomModel=true时生效)")] 231 public Color NodeSelectedForeColor 232 { 233 get 234 { 235 return this.m_nodeSelectedForeColor; 236 } 237 set 238 { 239 this.m_nodeSelectedForeColor = value; 240 } 241 } 242 243 [Category("自定义属性"), Description("父节点是否可选中")] 244 public bool ParentNodeCanSelect 245 { 246 get 247 { 248 return this._parentNodeCanSelect; 249 } 250 set 251 { 252 this._parentNodeCanSelect = value; 253 } 254 } 255 public TreeViewEx() 256 { 257 base.HideSelection = false; 258 base.DrawMode = TreeViewDrawMode.OwnerDrawAll; 259 base.DrawNode += new DrawTreeNodeEventHandler(this.treeview_DrawNode); 260 base.NodeMouseClick += new TreeNodeMouseClickEventHandler(this.TreeViewEx_NodeMouseClick); 261 base.SizeChanged += new EventHandler(this.TreeViewEx_SizeChanged); 262 base.AfterSelect += new TreeViewEventHandler(this.TreeViewEx_AfterSelect); 263 base.FullRowSelect = true; 264 base.ShowLines = false; 265 base.ShowPlusMinus = false; 266 base.ShowRootLines = false; 267 this.BackColor = Color.FromArgb(61, 60, 66); 268 DoubleBuffered = true; 269 } 270 protected override void WndProc(ref Message m) 271 { 272 273 if (m.Msg == 0x0014) // 禁掉清除背景消息WM_ERASEBKGND 274 275 return; 276 277 base.WndProc(ref m); 278 279 } 280 private void TreeViewEx_AfterSelect(object sender, TreeViewEventArgs e) 281 { 282 try 283 { 284 if (e.Node != null) 285 { 286 if (!this._parentNodeCanSelect) 287 { 288 if (e.Node.Nodes.Count > 0) 289 { 290 e.Node.Expand(); 291 base.SelectedNode = e.Node.Nodes[0]; 292 } 293 } 294 } 295 } 296 catch (Exception ex) 297 { 298 throw ex; 299 } 300 } 301 302 private void TreeViewEx_SizeChanged(object sender, EventArgs e) 303 { 304 this.Refresh(); 305 } 306 307 private void TreeViewEx_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) 308 { 309 try 310 { 311 if (e.Node != null) 312 { 313 if (e.Node.Nodes.Count > 0) 314 { 315 if (e.Node.IsExpanded) 316 { 317 e.Node.Collapse(); 318 } 319 else 320 { 321 e.Node.Expand(); 322 } 323 } 324 if (base.SelectedNode != null) 325 { 326 if (base.SelectedNode == e.Node && e.Node.IsExpanded) 327 { 328 if (!this._parentNodeCanSelect) 329 { 330 if (e.Node.Nodes.Count > 0) 331 { 332 base.SelectedNode = e.Node.Nodes[0]; 333 } 334 } 335 } 336 } 337 } 338 } 339 catch (Exception ex) 340 { 341 throw ex; 342 } 343 } 344 345 private void treeview_DrawNode(object sender, DrawTreeNodeEventArgs e) 346 { 347 try 348 { 349 if (e.Node == null || !this._isShowByCustomModel || (e.Node.Bounds.Width <= 0 && e.Node.Bounds.Height <= 0 && e.Node.Bounds.X <= 0 && e.Node.Bounds.Y <= 0)) 350 { 351 e.DrawDefault = true; 352 } 353 else 354 { 355 if (base.Nodes.IndexOf(e.Node) == 0) 356 { 357 this.blnHasVBar = this.IsVerticalScrollBarVisible(); 358 } 359 Font font = e.Node.NodeFont; 360 if (font == null) 361 { 362 font = ((TreeView)sender).Font; 363 } 364 if (this.treeFontSize == SizeF.Empty) 365 { 366 this.treeFontSize = this.GetFontSize(font, e.Graphics); 367 } 368 bool flag = false; 369 int num = 0; 370 if (base.ImageList != null && base.ImageList.Images.Count > 0 && e.Node.ImageIndex >= 0 && e.Node.ImageIndex < base.ImageList.Images.Count) 371 { 372 flag = true; 373 num = (e.Bounds.Height - base.ImageList.ImageSize.Height) / 2; 374 } 375 if ((e.State == TreeNodeStates.Selected || e.State == TreeNodeStates.Focused || e.State == (TreeNodeStates.Focused | TreeNodeStates.Selected)) && (this._parentNodeCanSelect || e.Node.Nodes.Count <= 0)) 376 { 377 e.Graphics.FillRectangle(new SolidBrush(this.m_nodeSelectedColor), new Rectangle(new Point(0, e.Node.Bounds.Y), new Size(base.Width, e.Node.Bounds.Height))); 378 e.Graphics.DrawString(e.Node.Text, font, new SolidBrush(this.m_nodeSelectedForeColor), (float)e.Bounds.X, (float)e.Bounds.Y + ((float)this._nodeHeight - this.treeFontSize.Height) / 2f); 379 } 380 else 381 { 382 e.Graphics.FillRectangle(new SolidBrush(this._nodeBackgroundColor), new Rectangle(new Point(0, e.Node.Bounds.Y), new Size(base.Width, e.Node.Bounds.Height))); 383 e.Graphics.DrawString(e.Node.Text, font, new SolidBrush(this._nodeForeColor), (float)e.Bounds.X, (float)e.Bounds.Y + ((float)this._nodeHeight - this.treeFontSize.Height) / 2f); 384 } 385 if (flag) 386 { 387 int num2 = e.Bounds.X - num - base.ImageList.ImageSize.Width; 388 if (num2 < 0) 389 { 390 num2 = 3; 391 } 392 e.Graphics.DrawImage(base.ImageList.Images[e.Node.ImageIndex], new Rectangle(new Point(num2, e.Bounds.Y + num), base.ImageList.ImageSize)); 393 } 394 if (this._nodeIsShowSplitLine) 395 { 396 e.Graphics.DrawLine(new Pen(this._nodeSplitLineColor, 1f), new Point(0, e.Bounds.Y + this._nodeHeight - 1), new Point(base.Width, e.Bounds.Y + this._nodeHeight - 1)); 397 } 398 bool flag2 = false; 399 if (e.Node.Nodes.Count > 0) 400 { 401 if (e.Node.IsExpanded && this._nodeUpPic != null) 402 { 403 e.Graphics.DrawImage(this._nodeUpPic, new Rectangle(base.Width - (this.blnHasVBar ? 50 : 30), e.Bounds.Y + (this._nodeHeight - 20) / 2, 20, 20)); 404 } 405 else if (this._nodeDownPic != null) 406 { 407 e.Graphics.DrawImage(this._nodeDownPic, new Rectangle(base.Width - (this.blnHasVBar ? 50 : 30), e.Bounds.Y + (this._nodeHeight - 20) / 2, 20, 20)); 408 } 409 flag2 = true; 410 } 411 if (this._isShowTip && this._lstTips.ContainsKey(e.Node.Name) && !string.IsNullOrWhiteSpace(this._lstTips[e.Node.Name])) 412 { 413 int num3 = base.Width - (this.blnHasVBar ? 50 : 30) - (flag2 ? 20 : 0); 414 int num4 = e.Bounds.Y + (this._nodeHeight - 20) / 2; 415 e.Graphics.DrawImage(this._tipImage, new Rectangle(num3, num4, 20, 20)); 416 SizeF sizeF = e.Graphics.MeasureString(this._lstTips[e.Node.Name], this._tipFont, 100, StringFormat.GenericTypographic); 417 e.Graphics.DrawString(this._lstTips[e.Node.Name], this._tipFont, new SolidBrush(Color.White), (float)(num3 + 10) - sizeF.Width / 2f - 3f, (float)(num4 + 10) - sizeF.Height / 2f); 418 } 419 } 420 } 421 catch (Exception ex) 422 { 423 throw ex; 424 } 425 } 426 427 private SizeF GetFontSize(Font font, Graphics g = null) 428 { 429 SizeF result; 430 try 431 { 432 bool flag = false; 433 if (g == null) 434 { 435 g = base.CreateGraphics(); 436 flag = true; 437 } 438 SizeF sizeF = g.MeasureString("a", font, 100, StringFormat.GenericTypographic); 439 if (flag) 440 { 441 g.Dispose(); 442 } 443 result = sizeF; 444 } 445 catch (Exception ex) 446 { 447 throw ex; 448 } 449 return result; 450 } 451 452 [DllImport("user32", CharSet = CharSet.Auto)] 453 private static extern int GetWindowLong(IntPtr hwnd, int nIndex); 454 455 private bool IsVerticalScrollBarVisible() 456 { 457 return base.IsHandleCreated && (TreeViewEx.GetWindowLong(base.Handle, -16) & 2097152) != 0; 458 } 459 } 460 }
用处及效果
用处:觉得原始的treeview太难看了,想换一种好看点的风格
效果:
调用示例
for (int i = 0; i < 3; i++) { TreeNode tn = new TreeNode(" 父节点" + i); for (int j = 0; j < 3; j++) { tn.Nodes.Add(" 子节点" + j); } this.treeViewEx1.Nodes.Add(tn); }
最后的话
如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星 星吧
作者:冰封一夏
出处:http://www.cnblogs.com/bfyx/
HZHControls官网:http://www.hzhcontrols.cn
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,
且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git