前提 入行已經7,8年了,一直想做一套漂亮點的自定義控制項,於是就有了本系列文章。 GitHub:https://github.com/kwwwvagaa/NetWinformControl 碼雲:https://gitee.com/kwwwvagaa/net_winform_custom_contr ...
前提
入行已經7,8年了,一直想做一套漂亮點的自定義控制項,於是就有了本系列文章。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
碼雲:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
如果覺得寫的還行,請點個 star 支持一下吧
來都來了,點個【推薦】再走吧,謝謝
NuGet
Install-Package HZH_Controls
目錄
https://www.cnblogs.com/bfyx/p/11364884.html
用處及效果
準備工作
沒什麼可準備的,直接開乾吧。
思路:
2個panel,分別放標題和明細
然後重繪控制項,在標題旁邊畫圓並且連線
開始
添加一個類來存放節點信息
1 public class TimeLineItem 2 { 3 /// <summary> 4 /// Gets or sets the title. 5 /// </summary> 6 /// <value>The title.</value> 7 public string Title { get; set; } 8 /// <summary> 9 /// Gets or sets the details. 10 /// </summary> 11 /// <value>The details.</value> 12 public string Details { get; set; } 13 }
添加一個用戶控制項UCTimeLine
添加一些屬性
1 /// <summary> 2 /// The line color 3 /// </summary> 4 private Color lineColor = TextColors.Light; 5 6 /// <summary> 7 /// Gets or sets the color of the line. 8 /// </summary> 9 /// <value>The color of the line.</value> 10 [Description("連接線顏色"), Category("自定義")] 11 public Color LineColor 12 { 13 get { return lineColor; } 14 set 15 { 16 lineColor = value; 17 Invalidate(); 18 } 19 } 20 /// <summary> 21 /// The title font 22 /// </summary> 23 private Font titleFont = new Font("微軟雅黑", 14f); 24 25 /// <summary> 26 /// Gets or sets the title font. 27 /// </summary> 28 /// <value>The title font.</value> 29 [Description("標題字體"), Category("自定義")] 30 public Font TitleFont 31 { 32 get { return titleFont; } 33 set 34 { 35 titleFont = value; 36 ReloadItems(); 37 } 38 } 39 40 /// <summary> 41 /// The title forcolor 42 /// </summary> 43 private Color titleForcolor = TextColors.MoreDark; 44 45 /// <summary> 46 /// Gets or sets the title forcolor. 47 /// </summary> 48 /// <value>The title forcolor.</value> 49 [Description("標題顏色"), Category("自定義")] 50 public Color TitleForcolor 51 { 52 get { return titleForcolor; } 53 set 54 { 55 titleForcolor = value; 56 ReloadItems(); 57 } 58 } 59 60 /// <summary> 61 /// The details font 62 /// </summary> 63 private Font detailsFont = new Font("微軟雅黑", 10); 64 65 /// <summary> 66 /// Gets or sets the details font. 67 /// </summary> 68 /// <value>The details font.</value> 69 [Description("詳情字體"), Category("自定義")] 70 public Font DetailsFont 71 { 72 get { return detailsFont; } 73 set 74 { 75 detailsFont = value; 76 ReloadItems(); 77 } 78 } 79 80 /// <summary> 81 /// The details forcolor 82 /// </summary> 83 private Color detailsForcolor = TextColors.Light; 84 85 /// <summary> 86 /// Gets or sets the details forcolor. 87 /// </summary> 88 /// <value>The details forcolor.</value> 89 [Description("詳情顏色"), Category("自定義")] 90 public Color DetailsForcolor 91 { 92 get { return detailsForcolor; } 93 set 94 { 95 detailsForcolor = value; 96 ReloadItems(); 97 } 98 } 99 100 /// <summary> 101 /// The items 102 /// </summary> 103 TimeLineItem[] items; 104 105 /// <summary> 106 /// Gets or sets the items. 107 /// </summary> 108 /// <value>The items.</value> 109 [Description("項列表"), Category("自定義")] 110 public TimeLineItem[] Items 111 { 112 get { return items; } 113 set 114 { 115 items = value; 116 ReloadItems(); 117 } 118 }
構造函數初始化一些東西
1 public UCTimeLine() 2 { 3 this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); 4 this.SetStyle(ControlStyles.DoubleBuffer, true); 5 this.SetStyle(ControlStyles.ResizeRedraw, true); 6 this.SetStyle(ControlStyles.Selectable, true); 7 this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); 8 this.SetStyle(ControlStyles.UserPaint, true); 9 InitializeComponent(); 10 items = new TimeLineItem[0]; 11 if (ControlHelper.IsDesignMode()) 12 { 13 items = new TimeLineItem[4]; 14 for (int i = 0; i < 4; i++) 15 { 16 items[i] = new TimeLineItem() 17 { 18 Title = DateTime.Now.AddMonths(-1 * (3 - i)).ToString("yyyy年MM月"), 19 Details = DateTime.Now.AddMonths(-1 * (3 - i)).ToString("yyyy年MM月") + "發生了一件大事,咔嚓一聲打了一個炸雷,咔嚓一聲打了一個炸雷,咔嚓一聲打了一個炸雷,咔嚓一聲打了一個炸雷,咔嚓一聲打了一個炸雷,咔嚓一聲打了一個炸雷,咔嚓一聲打了一個炸雷,咔嚓一聲打了一個炸雷,咔嚓一聲打了一個炸雷,然後王二麻子他爹王咔嚓出生了。" 20 }; 21 } 22 ReloadItems(); 23 } 24 }
重新載入列表
1 private void ReloadItems() 2 { 3 try 4 { 5 ControlHelper.FreezeControl(this, true); 6 this.Controls.Clear(); 7 if (items != null) 8 { 9 foreach (var item in items) 10 { 11 FlowLayoutPanel panelTitle = new FlowLayoutPanel(); 12 panelTitle.Dock = DockStyle.Top; 13 panelTitle.AutoScroll = false; 14 panelTitle.Padding = new System.Windows.Forms.Padding(5); 15 panelTitle.Name = "title_" + Guid.NewGuid().ToString(); 16 17 Label lblTitle = new Label(); 18 lblTitle.Dock = DockStyle.Top; 19 lblTitle.AutoSize = true; 20 lblTitle.Font = titleFont; 21 lblTitle.ForeColor = titleForcolor; 22 lblTitle.Text = item.Title; 23 lblTitle.SizeChanged += item_SizeChanged; 24 panelTitle.Controls.Add(lblTitle); 25 this.Controls.Add(panelTitle); 26 panelTitle.BringToFront(); 27 28 29 FlowLayoutPanel panelDetails = new FlowLayoutPanel(); 30 panelDetails.Dock = DockStyle.Top; 31 panelDetails.AutoScroll = false; 32 panelDetails.Padding = new System.Windows.Forms.Padding(5); 33 panelDetails.Name = "details_" + Guid.NewGuid().ToString(); 34 Label lblDetails = new Label(); 35 lblDetails.AutoSize = true; 36 lblDetails.Dock = DockStyle.Top; 37 lblDetails.Font = detailsFont; 38 lblDetails.ForeColor = detailsForcolor; 39 lblDetails.Text = item.Details; 40 lblDetails.SizeChanged += item_SizeChanged; 41 panelDetails.Controls.Add(lblDetails); 42 this.Controls.Add(panelDetails); 43 panelDetails.BringToFront(); 44 45 } 46 } 47 } 48 finally 49 { 50 ControlHelper.FreezeControl(this, false); 51 } 52 }
當文本大小改變時改變面板大小
1 void item_SizeChanged(object sender, EventArgs e) 2 { 3 Label lbl = (Label)sender; 4 lbl.Parent.Height = lbl.Height + 10; 5 }
重繪來畫圓和連線
1 protected override void OnPaint(PaintEventArgs e) 2 { 3 base.OnPaint(e); 4 var g = e.Graphics; 5 g.SetGDIHigh(); 6 var lst = this.Controls.ToArray().Where(p => p.Name.StartsWith("title_")).ToList(); 7 for (int i = 0; i < lst.Count; i++) 8 { 9 //畫圓 10 g.DrawEllipse(new Pen(new SolidBrush(lineColor)), new Rectangle(7, lst[i].Location.Y + 10, 16, 16)); 11 //劃線 12 if (i != lst.Count - 1) 13 { 14 g.DrawLine(new Pen(new SolidBrush(lineColor)), new Point(7 + 8, lst[i].Location.Y + 10 - 2), new Point(7 + 8, lst[i + 1].Location.Y + 10 + 16 + 2)); 15 } 16 } 17 }
最後的話
如果你喜歡的話,請到 https://gitee.com/kwwwvagaa/net_winform_custom_control 點個星星吧