入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
如果觉得写的还行,请点个 star 支持一下吧
欢迎前来交流探讨: 企鹅群568015492
来都来了,点个【推荐】再走吧,谢谢
Install-Package HZH_Controls
https://blog.csdn.net/kwwwvagaa/article/details/100586547
没什么可准备的,直接开干吧。
思路:
2个panel,分别放标题和明细
然后重绘控件,在标题旁边画圆并且连线
添加一个类来存放节点信息
1 public class TimeLineItem 2 { 3 ///4 /// Gets or sets the title. 5 /// 6 ///The title. 7 public string Title { get; set; } 8 ///9 /// Gets or sets the details. 10 /// 11 ///The details. 12 public string Details { get; set; } 13 }
添加一个用户控件UCTimeLine
添加一些属性
1 ///2 /// The line color 3 /// 4 private Color lineColor = TextColors.Light; 5 6 ///7 /// Gets or sets the color of the line. 8 /// 9 ///The color of the line. 10 [Description("连接线颜色"), Category("自定义")] 11 public Color LineColor 12 { 13 get { return lineColor; } 14 set 15 { 16 lineColor = value; 17 Invalidate(); 18 } 19 } 20 ///21 /// The title font 22 /// 23 private Font titleFont = new Font("微软雅黑", 14f); 24 25 ///26 /// Gets or sets the title font. 27 /// 28 ///The title font. 29 [Description("标题字体"), Category("自定义")] 30 public Font TitleFont 31 { 32 get { return titleFont; } 33 set 34 { 35 titleFont = value; 36 ReloadItems(); 37 } 38 } 39 40 ///41 /// The title forcolor 42 /// 43 private Color titleForcolor = TextColors.MoreDark; 44 45 ///46 /// Gets or sets the title forcolor. 47 /// 48 ///The title forcolor. 49 [Description("标题颜色"), Category("自定义")] 50 public Color TitleForcolor 51 { 52 get { return titleForcolor; } 53 set 54 { 55 titleForcolor = value; 56 ReloadItems(); 57 } 58 } 59 60 ///61 /// The details font 62 /// 63 private Font detailsFont = new Font("微软雅黑", 10); 64 65 ///66 /// Gets or sets the details font. 67 /// 68 ///The details font. 69 [Description("详情字体"), Category("自定义")] 70 public Font DetailsFont 71 { 72 get { return detailsFont; } 73 set 74 { 75 detailsFont = value; 76 ReloadItems(); 77 } 78 } 79 80 ///81 /// The details forcolor 82 /// 83 private Color detailsForcolor = TextColors.Light; 84 85 ///86 /// Gets or sets the details forcolor. 87 /// 88 ///The details forcolor. 89 [Description("详情颜色"), Category("自定义")] 90 public Color DetailsForcolor 91 { 92 get { return detailsForcolor; } 93 set 94 { 95 detailsForcolor = value; 96 ReloadItems(); 97 } 98 } 99 100 ///101 /// The items 102 /// 103 TimeLineItem[] items; 104 105 ///106 /// Gets or sets the items. 107 /// 108 ///The items. 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 点个星星吧