入行已经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
该控件是由多个按钮组合形成的,类似多选框和单选框,需要用到前面我们说到的控件UCBtnExt ,如果你对UCBtnExt 还不了解,请移步
我们先理一下思路,我们需要显示多个按钮,支持多选和单选,具有选中效果
我们先看下有哪些属性
1 /// <summary>
2 /// 选中改变事件
3 /// </summary>
4 public event EventHandler SelectedItemChanged;
5 private Dictionary<string, string> m_dataSource = new Dictionary<string, string>();
6 /// <summary>
7 /// 数据源
8 /// </summary>
9 public Dictionary<string, string> DataSource
10 {
11 get { return m_dataSource; }
12 set
13 {
14 m_dataSource = value;
15 Reload();
16 }
17 }
18
19 private List<string> m_selectItem = new List<string>();
20 /// <summary>
21 /// 选中项
22 /// </summary>
23 public List<string> SelectItem
24 {
25 get { return m_selectItem; }
26 set
27 {
28 m_selectItem = value;
29 if (m_selectItem == null)
30 m_selectItem = new List<string>();
31 SetSelected();
32 }
33 }
34
35 private bool m_isMultiple = false;
36 /// <summary>
37 /// 是否多选
38 /// </summary>
39 public bool IsMultiple
40 {
41 get { return m_isMultiple; }
42 set { m_isMultiple = value; }
43 }
当数据源改变的时候,需要加载按钮到面板上
1 private void Reload()
2 {
3 try
4 {
5 ControlHelper.FreezeControl(flowLayoutPanel1, true);
6 this.flowLayoutPanel1.Controls.Clear();
7 if (DataSource != null)
8 {
9 foreach (var item in DataSource)
10 {
11 UCBtnExt btn = new UCBtnExt();
12 btn.BackColor = System.Drawing.Color.Transparent;
13 btn.BtnBackColor = System.Drawing.Color.White;
14 btn.BtnFont = new System.Drawing.Font("微软雅黑", 10F);
15 btn.BtnForeColor = System.Drawing.Color.Gray;
16 btn.BtnText = item.Value;
17 btn.ConerRadius = 5;
18 btn.Cursor = System.Windows.Forms.Cursors.Hand;
19 btn.FillColor = System.Drawing.Color.White;
20 btn.Font = new System.Drawing.Font("微软雅黑", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel);
21 btn.IsRadius = true;
22 btn.IsShowRect = true;
23 btn.IsShowTips = false;
24 btn.Location = new System.Drawing.Point(5, 5);
25 btn.Margin = new System.Windows.Forms.Padding(5);
26 btn.Name = item.Key;
27 btn.RectColor = System.Drawing.Color.FromArgb(224, 224, 224);
28 btn.RectWidth = 1;
29 btn.Size = new System.Drawing.Size(72, 38);
30 btn.TabStop = false;
31 btn.BtnClick += btn_BtnClick;
32 this.flowLayoutPanel1.Controls.Add(btn);
33 }
34 }
35 }
36 finally
37 {
38 ControlHelper.FreezeControl(flowLayoutPanel1, false);
39 }
40 SetSelected();
41 }
42
43 void btn_BtnClick(object sender, EventArgs e)
44 {
45 var btn = sender as UCBtnExt;
46 if (m_selectItem.Contains(btn.Name))
47 {
48 btn.RectColor = System.Drawing.Color.FromArgb(224, 224, 224);
49 m_selectItem.Remove(btn.Name);
50 }
51 else
52 {
53 if (!m_isMultiple)
54 {
55 foreach (var item in m_selectItem)
56 {
57 var lst = this.flowLayoutPanel1.Controls.Find(item, false);
58 if (lst.Length == 1)
59 {
60 var _btn = lst[0] as UCBtnExt;
61 _btn.RectColor = System.Drawing.Color.FromArgb(224, 224, 224);
62 }
63 }
64 m_selectItem.Clear();
65 }
66 btn.RectColor = System.Drawing.Color.FromArgb(255, 77, 59);
67 m_selectItem.Add(btn.Name);
68 }
69 if (SelectedItemChanged != null)
70 SelectedItemChanged(this, e);
71 }
如果设置了初始选中项,那么还需要在加载后选中
1 private void SetSelected()
2 {
3 if (m_selectItem != null && m_selectItem.Count > 0 && DataSource != null && DataSource.Count > 0)
4 {
5 try
6 {
7 ControlHelper.FreezeControl(flowLayoutPanel1, true);
8 if (m_isMultiple)
9 {
10 foreach (var item in m_selectItem)
11 {
12 var lst = this.flowLayoutPanel1.Controls.Find(item, false);
13 if (lst.Length == 1)
14 {
15 var btn = lst[0] as UCBtnExt;
16 btn.RectColor = System.Drawing.Color.FromArgb(255, 77, 59);
17 }
18 }
19 }
20 else
21 {
22 UCBtnExt btn = null;
23 foreach (var item in m_selectItem)
24 {
25 var lst = this.flowLayoutPanel1.Controls.Find(item, false);
26 if (lst.Length == 1)
27 {
28 btn = lst[0] as UCBtnExt;
29 break;
30 }
31 }
32 if (btn != null)
33 {
34 m_selectItem = new List<string>() { btn.Name };
35 btn.RectColor = System.Drawing.Color.FromArgb(255, 77, 59);
36 }
37 }
38 }
39 finally
40 {
41 ControlHelper.FreezeControl(flowLayoutPanel1, false);
42 }
43 }
44 }
至此所有的逻辑已经处理完成,下面看下完整的代码吧
1 // 版权所有 黄正辉 交流群:568015492 QQ:623128629
2 // 文件名称:UCBtnsGroup.cs
3 // 创建日期:2019-08-15 15:58:13
4 // 功能描述:按钮组
5 // 项目地址:https://gitee.com/kwwwvagaa/net_winform_custom_control
6 using System;
7 using System.Collections.Generic;
8 using System.ComponentModel;
9 using System.Drawing;
10 using System.Data;
11 using System.Linq;
12 using System.Text;
13 using System.Windows.Forms;
14
15 namespace HZH_Controls.Controls
16 {
17 public partial class UCBtnsGroup : UserControl
18 {
19 /// <summary>
20 /// 选中改变事件
21 /// </summary>
22 public event EventHandler SelectedItemChanged;
23 private Dictionary<string, string> m_dataSource = new Dictionary<string, string>();
24 /// <summary>
25 /// 数据源
26 /// </summary>
27 public Dictionary<string, string> DataSource
28 {
29 get { return m_dataSource; }
30 set
31 {
32 m_dataSource = value;
33 Reload();
34 }
35 }
36
37 private List<string> m_selectItem = new List<string>();
38 /// <summary>
39 /// 选中项
40 /// </summary>
41 public List<string> SelectItem
42 {
43 get { return m_selectItem; }
44 set
45 {
46 m_selectItem = value;
47 if (m_selectItem == null)
48 m_selectItem = new List<string>();
49 SetSelected();
50 }
51 }
52
53 private bool m_isMultiple = false;
54 /// <summary>
55 /// 是否多选
56 /// </summary>
57 public bool IsMultiple
58 {
59 get { return m_isMultiple; }
60 set { m_isMultiple = value; }
61 }
62 public UCBtnsGroup()
63 {
64 InitializeComponent();
65 }
66
67 private void Reload()
68 {
69 try
70 {
71 ControlHelper.FreezeControl(flowLayoutPanel1, true);
72 this.flowLayoutPanel1.Controls.Clear();
73 if (DataSource != null)
74 {
75 foreach (var item in DataSource)
76 {
77 UCBtnExt btn = new UCBtnExt();
78 btn.BackColor = System.Drawing.Color.Transparent;
79 btn.BtnBackColor = System.Drawing.Color.White;
80 btn.BtnFont = new System.Drawing.Font("微软雅黑", 10F);
81 btn.BtnForeColor = System.Drawing.Color.Gray;
82 btn.BtnText = item.Value;
83 btn.ConerRadius = 5;
84 btn.Cursor = System.Windows.Forms.Cursors.Hand;
85 btn.FillColor = System.Drawing.Color.White;
86 btn.Font = new System.Drawing.Font("微软雅黑", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel);
87 btn.IsRadius = true;
88 btn.IsShowRect = true;
89 btn.IsShowTips = false;
90 btn.Location = new System.Drawing.Point(5, 5);
91 btn.Margin = new System.Windows.Forms.Padding(5);
92 btn.Name = item.Key;
93 btn.RectColor = System.Drawing.Color.FromArgb(224, 224, 224);
94 btn.RectWidth = 1;
95 btn.Size = new System.Drawing.Size(72, 38);
96 btn.TabStop = false;
97 btn.BtnClick += btn_BtnClick;
98 this.flowLayoutPanel1.Controls.Add(btn);
99 }
100 }
101 }
102 finally
103 {
104 ControlHelper.FreezeControl(flowLayoutPanel1, false);
105 }
106 SetSelected();
107 }
108
109 void btn_BtnClick(object sender, EventArgs e)
110 {
111 var btn = sender as UCBtnExt;
112 if (m_selectItem.Contains(btn.Name))
113 {
114 btn.RectColor = System.Drawing.Color.FromArgb(224, 224, 224);
115 m_selectItem.Remove(btn.Name);
116 }
117 else
118 {
119 if (!m_isMultiple)
120 {
121 foreach (var item in m_selectItem)
122 {
123 var lst = this.flowLayoutPanel1.Controls.Find(item, false);
124 if (lst.Length == 1)
125 {
126 var _btn = lst[0] as UCBtnExt;
127 _btn.RectColor = System.Drawing.Color.FromArgb(224, 224, 224);
128 }
129 }
130 m_selectItem.Clear();
131 }
132 btn.RectColor = System.Drawing.Color.FromArgb(255, 77, 59);
133 m_selectItem.Add(btn.Name);
134 }
135 if (SelectedItemChanged != null)
136 SelectedItemChanged(this, e);
137 }
138
139 private void SetSelected()
140 {
141 if (m_selectItem != null && m_selectItem.Count > 0 && DataSource != null && DataSource.Count > 0)
142 {
143 try
144 {
145 ControlHelper.FreezeControl(flowLayoutPanel1, true);
146 if (m_isMultiple)
147 {
148 foreach (var item in m_selectItem)
149 {
150 var lst = this.flowLayoutPanel1.Controls.Find(item, false);
151 if (lst.Length == 1)
152 {
153 var btn = lst[0] as UCBtnExt;
154 btn.RectColor = System.Drawing.Color.FromArgb(255, 77, 59);
155 }
156 }
157 }
158 else
159 {
160 UCBtnExt btn = null;
161 foreach (var item in m_selectItem)
162 {
163 var lst = this.flowLayoutPanel1.Controls.Find(item, false);
164 if (lst.Length == 1)
165 {
166 btn = lst[0] as UCBtnExt;
167 break;
168 }
169 }
170 if (btn != null)
171 {
172 m_selectItem = new List<string>() { btn.Name };
173 btn.RectColor = System.Drawing.Color.FromArgb(255, 77, 59);
174 }
175 }
176 }
177 finally
178 {
179 ControlHelper.FreezeControl(flowLayoutPanel1, false);
180 }
181 }
182 }
183 }
184 }
1 namespace HZH_Controls.Controls
2 {
3 partial class UCBtnsGroup
4 {
5 /// <summary>
6 /// 必需的设计器变量。
7 /// </summary>
8 private System.ComponentModel.IContainer components = null;
9
10 /// <summary>
11 /// 清理所有正在使用的资源。
12 /// </summary>
13 /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
14 protected override void Dispose(bool disposing)
15 {
16 if (disposing && (components != null))
17 {
18 components.Dispose();
19 }
20 base.Dispose(disposing);
21 }
22
23 #region 组件设计器生成的代码
24
25 /// <summary>
26 /// 设计器支持所需的方法 - 不要
27 /// 使用代码编辑器修改此方法的内容。
28 /// </summary>
29 private void InitializeComponent()
30 {
31 this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
32 this.SuspendLayout();
33 //
34 // flowLayoutPanel1
35 //
36 this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
37 this.flowLayoutPanel1.Location = new System.Drawing.Point(0, 0);
38 this.flowLayoutPanel1.Name = "flowLayoutPanel1";
39 this.flowLayoutPanel1.Size = new System.Drawing.Size(420, 50);
40 this.flowLayoutPanel1.TabIndex = 0;
41 //
42 // UCBtnsGroup
43 //
44 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
45 this.BackColor = System.Drawing.Color.White;
46 this.Controls.Add(this.flowLayoutPanel1);
47 this.MinimumSize = new System.Drawing.Size(0, 50);
48 this.Name = "UCBtnsGroup";
49 this.Size = new System.Drawing.Size(420, 50);
50 this.ResumeLayout(false);
51
52 }
53
54 #endregion
55
56 private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
57 }
58 }
用处:可以用选择按钮组来替换单选框和复选框,具有更和谐的界面效果
效果: