(四)c#Winform自定义控件-选择按钮组
官网
前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
如果觉得写的还行,请点个 star 支持一下吧
欢迎前来交流探讨: 企鹅群568015492 
目录
https://www.cnblogs.com/bfyx/p/11364884.html
准备工作
该控件是由多个按钮组合形成的,类似多选框和单选框,需要用到前面我们说到的控件UCBtnExt ,如果你对UCBtnExt 还不了解,请移步
我们先理一下思路,我们需要显示多个按钮,支持多选和单选,具有选中效果
开始
我们先看下有哪些属性
/// <summary>
/// 选中改变事件
/// </summary>
public event EventHandler SelectedItemChanged;
private Dictionary<string, string> m_dataSource = new Dictionary<string, string>();
/// <summary>
/// 数据源
/// </summary>
public Dictionary<string, string> DataSource
{
get { return m_dataSource; }
set
{
m_dataSource = value;
Reload();
}
} private List<string> m_selectItem = new List<string>();
/// <summary>
/// 选中项
/// </summary>
public List<string> SelectItem
{
get { return m_selectItem; }
set
{
m_selectItem = value;
if (m_selectItem == null)
m_selectItem = new List<string>();
SetSelected();
}
} private bool m_isMultiple = false;
/// <summary>
/// 是否多选
/// </summary>
public bool IsMultiple
{
get { return m_isMultiple; }
set { m_isMultiple = value; }
}
当数据源改变的时候,需要加载按钮到面板上
private void Reload()
{
try
{
ControlHelper.FreezeControl(flowLayoutPanel1, true);
this.flowLayoutPanel1.Controls.Clear();
if (DataSource != null)
{
foreach (var item in DataSource)
{
UCBtnExt btn = new UCBtnExt();
btn.BackColor = System.Drawing.Color.Transparent;
btn.BtnBackColor = System.Drawing.Color.White;
btn.BtnFont = new System.Drawing.Font("微软雅黑", 10F);
btn.BtnForeColor = System.Drawing.Color.Gray;
btn.BtnText = item.Value;
btn.ConerRadius = ;
btn.Cursor = System.Windows.Forms.Cursors.Hand;
btn.FillColor = System.Drawing.Color.White;
btn.Font = new System.Drawing.Font("微软雅黑", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel);
btn.IsRadius = true;
btn.IsShowRect = true;
btn.IsShowTips = false;
btn.Location = new System.Drawing.Point(, );
btn.Margin = new System.Windows.Forms.Padding();
btn.Name = item.Key;
btn.RectColor = System.Drawing.Color.FromArgb(, , );
btn.RectWidth = ;
btn.Size = new System.Drawing.Size(, );
btn.TabStop = false;
btn.BtnClick += btn_BtnClick;
this.flowLayoutPanel1.Controls.Add(btn);
}
}
}
finally
{
ControlHelper.FreezeControl(flowLayoutPanel1, false);
}
SetSelected();
} void btn_BtnClick(object sender, EventArgs e)
{
var btn = sender as UCBtnExt;
if (m_selectItem.Contains(btn.Name))
{
btn.RectColor = System.Drawing.Color.FromArgb(, , );
m_selectItem.Remove(btn.Name);
}
else
{
if (!m_isMultiple)
{
foreach (var item in m_selectItem)
{
var lst = this.flowLayoutPanel1.Controls.Find(item, false);
if (lst.Length == )
{
var _btn = lst[] as UCBtnExt;
_btn.RectColor = System.Drawing.Color.FromArgb(, , );
}
}
m_selectItem.Clear();
}
btn.RectColor = System.Drawing.Color.FromArgb(, , );
m_selectItem.Add(btn.Name);
}
if (SelectedItemChanged != null)
SelectedItemChanged(this, e);
}
如果设置了初始选中项,那么还需要在加载后选中
private void SetSelected()
{
if (m_selectItem != null && m_selectItem.Count > && DataSource != null && DataSource.Count > )
{
try
{
ControlHelper.FreezeControl(flowLayoutPanel1, true);
if (m_isMultiple)
{
foreach (var item in m_selectItem)
{
var lst = this.flowLayoutPanel1.Controls.Find(item, false);
if (lst.Length == )
{
var btn = lst[] as UCBtnExt;
btn.RectColor = System.Drawing.Color.FromArgb(, , );
}
}
}
else
{
UCBtnExt btn = null;
foreach (var item in m_selectItem)
{
var lst = this.flowLayoutPanel1.Controls.Find(item, false);
if (lst.Length == )
{
btn = lst[] as UCBtnExt;
break;
}
}
if (btn != null)
{
m_selectItem = new List<string>() { btn.Name };
btn.RectColor = System.Drawing.Color.FromArgb(, , );
}
}
}
finally
{
ControlHelper.FreezeControl(flowLayoutPanel1, false);
}
}
}
至此所有的逻辑已经处理完成,下面看下完整的代码吧
// 版权所有 黄正辉 交流群:568015492 QQ:623128629
// 文件名称:UCBtnsGroup.cs
// 创建日期:2019-08-15 15:58:13
// 功能描述:按钮组
// 项目地址:https://gitee.com/kwwwvagaa/net_winform_custom_control
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms; namespace HZH_Controls.Controls
{
public partial class UCBtnsGroup : UserControl
{
/// <summary>
/// 选中改变事件
/// </summary>
public event EventHandler SelectedItemChanged;
private Dictionary<string, string> m_dataSource = new Dictionary<string, string>();
/// <summary>
/// 数据源
/// </summary>
public Dictionary<string, string> DataSource
{
get { return m_dataSource; }
set
{
m_dataSource = value;
Reload();
}
} private List<string> m_selectItem = new List<string>();
/// <summary>
/// 选中项
/// </summary>
public List<string> SelectItem
{
get { return m_selectItem; }
set
{
m_selectItem = value;
if (m_selectItem == null)
m_selectItem = new List<string>();
SetSelected();
}
} private bool m_isMultiple = false;
/// <summary>
/// 是否多选
/// </summary>
public bool IsMultiple
{
get { return m_isMultiple; }
set { m_isMultiple = value; }
}
public UCBtnsGroup()
{
InitializeComponent();
} private void Reload()
{
try
{
ControlHelper.FreezeControl(flowLayoutPanel1, true);
this.flowLayoutPanel1.Controls.Clear();
if (DataSource != null)
{
foreach (var item in DataSource)
{
UCBtnExt btn = new UCBtnExt();
btn.BackColor = System.Drawing.Color.Transparent;
btn.BtnBackColor = System.Drawing.Color.White;
btn.BtnFont = new System.Drawing.Font("微软雅黑", 10F);
btn.BtnForeColor = System.Drawing.Color.Gray;
btn.BtnText = item.Value;
btn.ConerRadius = ;
btn.Cursor = System.Windows.Forms.Cursors.Hand;
btn.FillColor = System.Drawing.Color.White;
btn.Font = new System.Drawing.Font("微软雅黑", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel);
btn.IsRadius = true;
btn.IsShowRect = true;
btn.IsShowTips = false;
btn.Location = new System.Drawing.Point(, );
btn.Margin = new System.Windows.Forms.Padding();
btn.Name = item.Key;
btn.RectColor = System.Drawing.Color.FromArgb(, , );
btn.RectWidth = ;
btn.Size = new System.Drawing.Size(, );
btn.TabStop = false;
btn.BtnClick += btn_BtnClick;
this.flowLayoutPanel1.Controls.Add(btn);
}
}
}
finally
{
ControlHelper.FreezeControl(flowLayoutPanel1, false);
}
SetSelected();
} void btn_BtnClick(object sender, EventArgs e)
{
var btn = sender as UCBtnExt;
if (m_selectItem.Contains(btn.Name))
{
btn.RectColor = System.Drawing.Color.FromArgb(, , );
m_selectItem.Remove(btn.Name);
}
else
{
if (!m_isMultiple)
{
foreach (var item in m_selectItem)
{
var lst = this.flowLayoutPanel1.Controls.Find(item, false);
if (lst.Length == )
{
var _btn = lst[] as UCBtnExt;
_btn.RectColor = System.Drawing.Color.FromArgb(, , );
}
}
m_selectItem.Clear();
}
btn.RectColor = System.Drawing.Color.FromArgb(, , );
m_selectItem.Add(btn.Name);
}
if (SelectedItemChanged != null)
SelectedItemChanged(this, e);
} private void SetSelected()
{
if (m_selectItem != null && m_selectItem.Count > && DataSource != null && DataSource.Count > )
{
try
{
ControlHelper.FreezeControl(flowLayoutPanel1, true);
if (m_isMultiple)
{
foreach (var item in m_selectItem)
{
var lst = this.flowLayoutPanel1.Controls.Find(item, false);
if (lst.Length == )
{
var btn = lst[] as UCBtnExt;
btn.RectColor = System.Drawing.Color.FromArgb(, , );
}
}
}
else
{
UCBtnExt btn = null;
foreach (var item in m_selectItem)
{
var lst = this.flowLayoutPanel1.Controls.Find(item, false);
if (lst.Length == )
{
btn = lst[] as UCBtnExt;
break;
}
}
if (btn != null)
{
m_selectItem = new List<string>() { btn.Name };
btn.RectColor = System.Drawing.Color.FromArgb(, , );
}
}
}
finally
{
ControlHelper.FreezeControl(flowLayoutPanel1, false);
}
}
}
}
}
namespace HZH_Controls.Controls
{
partial class UCBtnsGroup
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null; /// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
} #region 组件设计器生成的代码 /// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
this.SuspendLayout();
//
// flowLayoutPanel1
//
this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.flowLayoutPanel1.Location = new System.Drawing.Point(, );
this.flowLayoutPanel1.Name = "flowLayoutPanel1";
this.flowLayoutPanel1.Size = new System.Drawing.Size(, );
this.flowLayoutPanel1.TabIndex = ;
//
// UCBtnsGroup
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.BackColor = System.Drawing.Color.White;
this.Controls.Add(this.flowLayoutPanel1);
this.MinimumSize = new System.Drawing.Size(, );
this.Name = "UCBtnsGroup";
this.Size = new System.Drawing.Size(, );
this.ResumeLayout(false); } #endregion private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
}
}
用处及效果
用处:可以用选择按钮组来替换单选框和复选框,具有更和谐的界面效果
效果:

最后的话
如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧
(四)c#Winform自定义控件-选择按钮组的更多相关文章
- c#Winform自定义控件-目录
		
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
 - winform 自定义控件(高手)
		
高手推荐:https://www.cnblogs.com/bfyx/p/11364884.html c#Winform自定义控件-目录 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件 ...
 - (三十一)c#Winform自定义控件-文本框(四)
		
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
 - (四十二)c#Winform自定义控件-进度条扩展
		
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...
 - (四十九)c#Winform自定义控件-下拉框(表格)
		
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...
 - (四十六)c#Winform自定义控件-水波进度条-HZHControls
		
官网 http://www.hzhcontrols.com 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kww ...
 - (二十四)c#Winform自定义控件-单标题窗体
		
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
 - (四十一)c#Winform自定义控件-进度条
		
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
 - (四十五)c#Winform自定义控件-水波图表
		
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...
 
随机推荐
- 使用nexus搭建npm私服
			
第一步,下载nexus 下载链接: https://pan.baidu.com/s/1GOYi2M3nT4Wcy7JEYmnqdA 提取码: a9hf 第二步,解压缩 我下载的是nexus-3.16. ...
 - Linux系统下word转pdf,xls转pdf,ppt转pdf
			
word转换pdf的技术方案,供参考.[doc/docx/ppt/pptx/xls/xlsx均支持转换] 本方案是Java结合shell命令完成,不同于以往的仅依赖java组件转换 ...
 - vue组件间通信六种方式(完整版)
			
本文总结了vue组件间通信的几种方式,如props. $emit/ $on.vuex. $parent / $children. $attrs/ $listeners和provide/inject,以 ...
 - MyBatis从入门到精通:update用法、delete用法
			
update用法: 1.接口类中添加的方法: int updateById(SysUser sysUser); 2.映射文件中添加的代码: <update id="updateById ...
 - LoadRunner Community Edition 12.60 无法获取Community License
			
更新:该问题于2018/9/28已修复.附邮件: Hi Morris, Thank you for your update. I would like to tell you that we had ...
 - java高并发系列 - 第14天:JUC中的LockSupport工具类,必备技能
			
这是java高并发系列第14篇文章. 本文主要内容: 讲解3种让线程等待和唤醒的方法,每种方法配合具体的示例 介绍LockSupport主要用法 对比3种方式,了解他们之间的区别 LockSuppor ...
 - 【HDU - 3533】Escape(bfs)
			
Escape Descriptions: 一个人从(0,0)跑到(n,m),只有k点能量,一秒消耗一点,在图中有k个炮塔,给出炮塔的射击方向c,射击间隔t,子弹速度v,坐标x,y问这个人能不能安全到 ...
 - something good
			
CF292A CF304B CF383A CF409D CF409F CF632A CF652B CF656A CF656B CF656D CF659A CF678A CF697A CF735D CF ...
 - 关于RedirectAttributes 重定向带参数请求问题
			
@RequestMapping("/delete") public String delete(String id, RedirectAttributes redirectAttr ...
 - python注释-输入输出-基本数据类型-运算符
			
python注释 用处:注释用来书写一些解释性信息,对代码的逻辑作用等作出描述 单行注释.多行注释 # 这是行注释,注释内容与# 之间要空一格 print("hello world!&quo ...