入行已经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);
}