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 }