前提

入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。

开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control
<https://gitee.com/kwwwvagaa/net_winform_custom_control>

如果觉得写的还行,请点个 star 支持一下吧

欢迎前来交流探讨: 企鹅群568015492 
<https://shang.qq.com/wpa/qunwpa?idkey=6e08741ef16fe53bf0314c1c9e336c4f626047943a8b76bac062361bab6b4f8d>

目录

https://www.cnblogs.com/bfyx/p/11364884.html
<https://www.cnblogs.com/bfyx/p/11364884.html>

准备工作

该控件是由多个按钮组合形成的,类似多选框和单选框,需要用到前面我们说到的控件UCBtnExt ,如果你对UCBtnExt 还不了解,请移步

(二)c#Winform自定义控件-按钮 <https://www.cnblogs.com/bfyx/p/11361894.html> 查看

我们先理一下思路,我们需要显示多个按钮,支持多选和单选,具有选中效果

开始

我们先看下有哪些属性
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
= senderas 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 } View Code 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 //
UCBtnsGroup43 // 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 } View Code
用处及效果

用处:可以用选择按钮组来替换单选框和复选框,具有更和谐的界面效果

效果:



最后的话

如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control
<https://gitee.com/kwwwvagaa/net_winform_custom_control> 点个星星吧

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信