C# Winform treeview重繪


效果圖:

 

  1 using System;
  2 using System.ComponentModel;
  3 using System.Drawing;
  4 using System.Drawing.Drawing2D;
  5 using System.Windows.Forms;
  6 
  7 namespace LeaderMap.Resource
  8 {
  9     /// <summary>
 10     /// 基於樹視圖的任務控件
 11     /// </summary>
 12     public class CTreeTaskBox : TreeView
 13     {
 14         #region //construckor
 15         /// <summary>
 16         /// 
 17         /// </summary>
 18         public CTreeTaskBox()
 19         {
 20             FullRowSelect = true;
 21             ShowLines = true;
 22             this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
 23             this.DrawMode = TreeViewDrawMode.OwnerDrawAll;
 24             this.ItemHeight = 30;
 25             this.ShowLines = true;
 26         }
 27         #endregion
 28         #region //field & property
 29         /// <summary>
 30         /// 展開按扭的大小
 31         /// </summary>
 32         private Size ExpandButtonSize = new Size(16, 16);
 33         private Color _ExpandButtonColor = Color.FromArgb(255, 255, 255);
 34         /// <summary>
 35         /// 展開按扭顏色
 36         /// </summary>
 37         [Description("展開按扭顏色"), Category("XOProperty")]
 38         public Color ExpandButtonColor
 39         {
 40             get
 41             {
 42                 return _ExpandButtonColor;
 43             }
 44             set
 45             {
 46                 if (_ExpandButtonColor != value)
 47                 {
 48                     _ExpandButtonColor = value;
 49                     this.Invalidate();
 50                 }
 51             }
 52         }
 53         private Color _GroupBgColor = Color.FromArgb(95, 162, 211);
 54         /// <summary>
 55         /// 分組欄背景色
 56         /// </summary>
 57         [Description("分組欄背景色"), Category("XOProperty")]
 58         public Color GroupBgColor
 59         {
 60             get
 61             {
 62                 return _GroupBgColor;
 63             }
 64             set
 65             {
 66                 if (_GroupBgColor != value)
 67                 {
 68                     _GroupBgColor = value;
 69                     this.Invalidate();
 70 
 71                 }
 72             }
 73         }
 74         private Color _GroupTitleColor = Color.FromArgb(0, 0, 0);
 75         /// <summary>
 76         /// 分組欄標題色
 77         /// </summary>
 78         [Description("分組欄標題色"), Category("XOProperty")]
 79         public Color GroupTitleColor
 80         {
 81             get
 82             {
 83                 return _GroupTitleColor;
 84             }
 85             set
 86             {
 87                 if (_GroupTitleColor != value)
 88                 {
 89                     _GroupTitleColor = value;
 90                     this.Invalidate();
 91                 }
 92             }
 93         }
 94         private Color _OverForeColor = Color.DeepSkyBlue;
 95         /// <summary>
 96         /// 鼠標懸停色
 97         /// </summary>
 98         [Description("鼠標懸停色"), Category("XOProperty")]
 99         public Color OverForeColor
100         {
101             get
102             {
103                 return _OverForeColor;
104             }
105             set
106             {
107                 if (_OverForeColor != value)
108                 {
109                     _OverForeColor = value;
110                     this.Invalidate();
111                 }
112             }
113         }
114         /// <summary>
115         /// 節點高度
116         /// </summary>
117         public new int ItemHeight
118         {
119             get
120             {
121                 return base.ItemHeight;
122             }
123             set
124             {
125                 if (base.ItemHeight != value && value >= 20)
126                 {
127                     base.ItemHeight = value;
128                     this.Invalidate();
129                 }
130             }
131         }
132 
133         #endregion
134         #region //override
135         protected override void OnDrawNode(DrawTreeNodeEventArgs e)
136         {
137             //base.OnDrawNode(e);
138             DrawNodeItem(e);
139         }
140         protected override void WndProc(ref Message m)
141         {
142 
143             if (m.Msg == 0x0201)//單擊
144             {
145                 int wparam = m.LParam.ToInt32();
146                 Point point = new Point(
147                     LOWORD(wparam),
148                     HIWORD(wparam));
149                 //point = PointToClient(point);
150                 TreeNode tn = this.GetNodeAt(point);
151                 if (tn == null)
152                 {
153                     base.WndProc(ref m);
154                     return;
155                 }
156                 if (tn.Level == 0)
157                 {
158                     if (tn.IsExpanded)
159                     {
160                         tn.Collapse();
161                     }
162                     else
163                     {
164                         tn.Expand();
165                     }
166                     m.Result = IntPtr.Zero;
167                     return;
168                 }
169                 else
170                 {
171                     base.WndProc(ref m);
172                     //tn.IsSelected = true;
173                     //this.SelectedNode = tn;
174                 }
175                 this.SelectedNode = tn;
176             }
177             else if (m.Msg == 0x0203)//雙擊
178             {
179                 int wparam = m.LParam.ToInt32();
180                 Point point = new Point(
181                     LOWORD(wparam),
182                     HIWORD(wparam));
183                 //point = PointToClient(point);
184                 TreeNode tn = this.GetNodeAt(point);
185                 if (tn == null)
186                 {
187                     base.WndProc(ref m);
188                     return;
189                 }
190                 if (tn.Level == 0)
191                 {
192                     m.Result = IntPtr.Zero;
193                     return;
194                 }
195                 else
196                 {
197                     base.WndProc(ref m);
198                 }
199                 this.SelectedNode = tn;
200             }
201             else if (m.Msg == 0x0200)//鼠標移動
202             {
203                 try
204                 {
205                     int wparam = m.LParam.ToInt32();
206                     Point point = new Point(
207                         LOWORD(wparam),
208                         HIWORD(wparam));
209                     //point = PointToClient(point);
210                     TreeNode tn = this.GetNodeAt(point);
211                     if (tn == null)
212                     {
213                         // this.SelectedNode = null;
214                         base.WndProc(ref m);
215                         return;
216                     }
217                     //this.SelectedNode = tn;
218                 }
219                 catch { }
220             }
221             else if (m.Msg == 0x02A3)//鼠標移出 WM_MOUSELEAVE = $02A3;
222             {
223                 // this.SelectedNode = null;
224                 base.WndProc(ref m);
225                 return;
226             }
227             else
228             {
229                 base.WndProc(ref m);
230             }
231             //WM_LBUTTONDOWN = $0201
232             //WM_LBUTTONDBLCLK = $0203;
233         }
234         #endregion
235 
236         #region //private method
237         /// <summary>
238         /// 自定義繪制節點
239         /// </summary>
240         /// <param name="e"></param>
241         private void DrawNodeItem(DrawTreeNodeEventArgs e)
242         {
243             TreeNode tn = e.Node;
244             if (tn.Level == 0)
245             {
246                 using (Graphics g = e.Graphics)
247                 {
248                     //繪制分組的背景
249                     RenderBackgroundInternalRate(g,
250                         e.Bounds,
251                         GroupBgColor,
252                         GroupBgColor,
253                         Color.FromArgb(200, 255, 255, 255),
254                         0.45f,
255                         true,
256                         300);
257                     //繪制展開按扭
258                     g.FillEllipse(new SolidBrush(ExpandButtonColor), ExpandButtonBounds(e.Bounds));
259                     g.DrawEllipse(new Pen(Color.LightGray), ExpandButtonBounds(e.Bounds));
260                     Point p1;
261                     Point p2;
262                     Point p3;
263                     if (tn.IsExpanded)
264                     {
265                         p1 = new Point(ExpandButtonBounds(e.Bounds).X + 3, ExpandButtonBounds(e.Bounds).Bottom - 4);
266                         p2 = new Point(ExpandButtonBounds(e.Bounds).X + (ExpandButtonSize.Width) / 2, ExpandButtonBounds(e.Bounds).Top + 5);
267                         p3 = new Point(ExpandButtonBounds(e.Bounds).Right - 3, ExpandButtonBounds(e.Bounds).Bottom - 4);
268                     }
269                     else
270                     {
271                         p1 = new Point(ExpandButtonBounds(e.Bounds).X + 3, ExpandButtonBounds(e.Bounds).Y + 4);
272                         p2 = new Point(ExpandButtonBounds(e.Bounds).X + (ExpandButtonSize.Width) / 2, ExpandButtonBounds(e.Bounds).Bottom - 5);
273                         p3 = new Point(ExpandButtonBounds(e.Bounds).Right - 3, ExpandButtonBounds(e.Bounds).Y + 4);
274                     }
275                     GraphicsPath gp = new GraphicsPath();
276                     gp.AddLine(p1, p2);
277                     gp.AddLine(p2, p3);
278                     g.DrawPath(new Pen(Color.FromArgb(255, 150, 0, 0), 2f), gp);
279 
280                     //繪制分組的文本
281                     TextRenderer.DrawText(g, e.Node.Text, this.Font, GroupTitleBounds(e.Bounds), this.GroupTitleColor,
282                         TextFormatFlags.Left | TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis);
283                 }
284             }
285             else if (tn.Level == 1)
286             {
287                 //e.DrawDefault = true;
288 
289                 using (Graphics g = e.Graphics)
290                 {
291                     if (tn.IsSelected)
292                     {
293                         TextRenderer.DrawText(g, e.Node.Text, new Font(this.Font.FontFamily.Name, this.Font.Size, FontStyle.Underline), e.Bounds, OverForeColor,
294                                 TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
295                     }
296                     else
297                     {
298                         TextRenderer.DrawText(g, e.Node.Text, this.Font, e.Bounds, this.ForeColor,
299                                 TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
300                     }
301                 }
302             }
303         }
304         /// <summary>
305         /// 展開按扭區域  一級菜單后面的展開按鈕
306         /// </summary>
307         /// <param name="childRect"></param>
308         /// <returns></returns>
309         private Rectangle ExpandButtonBounds(Rectangle childRect)
310         {
311             Rectangle lrect = new Rectangle(new Point(childRect.Right - ExpandButtonSize.Width * 3 / 2, (childRect.Height - ExpandButtonSize.Height) / 2 + childRect.Top), ExpandButtonSize);
312             return lrect;
313         }
314         /// <summary>
315         /// 取得分組標題繪制空間  一級菜單
316         /// </summary>
317         /// <param name="childRect"></param>
318         /// <returns></returns>
319         private Rectangle GroupTitleBounds(Rectangle childRect)
320         {
321             Rectangle lrect = childRect;
322             lrect.Width -= ExpandButtonSize.Width * 3 / 2 + 20;
323             lrect.Offset(20, 0);
324             return lrect;
325         }
326         #endregion
327 
328         #region //draw
329         internal void RenderBackgroundInternal(
330    Graphics g,
331    Rectangle rect,
332    Color baseColor,
333    Color borderColor,
334    Color innerBorderColor,
335    float basePosition,
336    bool drawBorder,
337    LinearGradientMode mode)
338         {
339             if (drawBorder)
340             {
341                 rect.Width--;
342                 rect.Height--;
343             }
344             using (LinearGradientBrush brush = new LinearGradientBrush(
345                rect, Color.Transparent, Color.Transparent, mode))
346             {
347                 Color[] colors = new Color[4];
348                 colors[0] = GetColor(baseColor, 0, 35, 24, 9);
349                 colors[1] = GetColor(baseColor, 0, 13, 8, 3);
350                 colors[2] = baseColor;
351                 colors[3] = GetColor(baseColor, 0, 68, 69, 54);
352                 ColorBlend blend = new ColorBlend();
353                 blend.Positions = new float[] { 0.0f, basePosition, basePosition + 0.05f, 1.0f };
354                 blend.Colors = colors;
355                 brush.InterpolationColors = blend;
356                 g.FillRectangle(brush, rect);
357             }
358             if (baseColor.A > 80)
359             {
360                 Rectangle rectTop = rect;
361                 if (mode == LinearGradientMode.Vertical)
362                 {
363                     rectTop.Height = (int)(rectTop.Height * basePosition);
364                 }
365                 else
366                 {
367                     rectTop.Width = (int)(rect.Width * basePosition);
368                 }
369                 using (SolidBrush brushAlpha =
370                     new SolidBrush(Color.FromArgb(80, 255, 255, 255)))
371                 {
372                     g.FillRectangle(brushAlpha, rectTop);
373                 }
374             }
375             if (drawBorder)
376             {
377                 using (Pen pen = new Pen(borderColor))
378                 {
379                     g.DrawRectangle(pen, rect);
380                 }
381                 rect.Inflate(-1, -1);
382                 using (Pen pen = new Pen(innerBorderColor))
383                 {
384                     g.DrawRectangle(pen, rect);
385                 }
386             }
387         }
388         internal void RenderBackgroundInternalRate(
389    Graphics g,
390    Rectangle rect,
391    Color baseColor,
392    Color borderColor,
393    Color innerBorderColor,
394    float basePosition,
395    bool drawBorder, float rate)
396         {
397             if (drawBorder)
398             {
399                 rect.Width--;
400                 rect.Height--;
401             }
402             using (LinearGradientBrush brush = new LinearGradientBrush(
403                rect, Color.Transparent, Color.Transparent, rate))
404             {
405                 Color[] colors = new Color[4];
406                 colors[0] = GetColor(baseColor, 0, 35, 24, 9);
407                 colors[1] = GetColor(baseColor, 0, 13, 8, 3);
408                 colors[2] = baseColor;
409                 colors[3] = GetColor(baseColor, 0, 68, 69, 54);
410                 ColorBlend blend = new ColorBlend();
411                 blend.Positions = new float[] { 0.0f, basePosition, basePosition + 0.05f, 1.0f };
412                 blend.Colors = colors;
413                 brush.InterpolationColors = blend;
414                 g.FillRectangle(brush, rect);
415             }
416             if (baseColor.A > 80)
417             {
418                 Rectangle rectTop = rect;
419                 if (true/*mode == LinearGradientMode.Vertical*/)
420                 {
421                     rectTop.Height = (int)(rectTop.Height * basePosition);
422                 }
423                 else
424                 {
425                     rectTop.Width = (int)(rect.Width * basePosition);
426                 }
427                 using (SolidBrush brushAlpha =
428                     new SolidBrush(Color.FromArgb(80, 255, 255, 255)))
429                 {
430                     g.FillRectangle(brushAlpha, rectTop);
431                 }
432             }
433             if (drawBorder)
434             {
435                 using (Pen pen = new Pen(borderColor))
436                 {
437                     g.DrawRectangle(pen, rect);
438                 }
439                 rect.Inflate(-1, -1);
440                 using (Pen pen = new Pen(innerBorderColor))
441                 {
442                     g.DrawRectangle(pen, rect);
443                 }
444             }
445         }
446 
447         private Color GetColor(Color colorBase, int a, int r, int g, int b)
448         {
449             int a0 = colorBase.A;
450             int r0 = colorBase.R;
451             int g0 = colorBase.G;
452             int b0 = colorBase.B;
453             if (a + a0 > 255) { a = 255; } else { a = a + a0; }
454             if (r + r0 > 255) { r = 255; } else { r = r + r0; }
455             if (g + g0 > 255) { g = 255; } else { g = g + g0; }
456             if (b + b0 > 255) { b = 255; } else { b = b + b0; }
457             return Color.FromArgb(a, r, g, b);
458         }
459         private Color GetColor2(Color colorBase, int a, int r, int g, int b)
460         {
461             int a0 = colorBase.A;
462             int r0 = colorBase.R;
463             int g0 = colorBase.G;
464             int b0 = colorBase.B;
465             if (a + a0 > 255) { a = 255; } else { a = a + a0; }
466             if (r0 - r < 0) { r = 0; } else { r = r0 - r; }
467             if (g0 - g < 0) { g = 0; } else { g = g0 - g; }
468             if (b0 - b < 0) { b = 0; } else { b = b0 - b; }
469             return Color.FromArgb(a, r, g, b);
470         }
471         #endregion
472         public static int LOWORD(int value)
473         {
474             return value & 0xFFFF;
475         }
476         public static int HIWORD(int value)
477         {
478             return value >> 16;
479         }
480     }
481 }

 

來源:

自定義繪制treeview,重繪treeview - 無名劍(游維3d虛擬現實及游戲開發) - 博客頻道 - CSDN.NET
http://blog.csdn.net/nnsword/article/details/5291949

稍作修改.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM