C# WinForm 自定义控件 DataGridView 支持序号、列标注、自定义按钮
C# WinForm 控件 DataGridView 支持序号、列标注、自定义按钮
----------------------------------
-----文章末尾看效果--------
----------------------------------
新建文件 DataGridViewBlue.cs
拷贝如下代码
using IntergratedTestTooling.Db.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace IntergratedTestTooling
{
/// <summary>
/// 数据网格(蓝色主题)
/// </summary>
public class DataGridViewBlue : DataGridView
{
Color bc = Color.FromArgb(0, 102, 153);//深蓝色
Color bc2 = Color.FromArgb(204, 204, 204);//米白色
public delegate void DataGridViewCellButtonEventHandler(object sender, DataGridViewCellButtonEventArgs e);
/// <summary>
/// 点击单元格里面的按钮触发
/// </summary>
public event DataGridViewCellButtonEventHandler CellButtonClick;
public DataGridViewBlue()
{
//事件
this.CellClick += DataGridViewBlue_CellClick;
this.RowPostPaint += DataGridViewBlue_RowPostPaint;
//蓝色背景
this.BackgroundColor = Color.FromArgb(51, 138, 173);
//不要边框
this.BorderStyle = BorderStyle.None;
//不要左边的
this.RowHeadersVisible = false;
//平均分配列宽
this.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
//选中单元格
this.SelectionMode = DataGridViewSelectionMode.RowHeaderSelect;
//不可编辑
this.EditMode = DataGridViewEditMode.EditProgrammatically;
this.AllowUserToAddRows = false;
this.AllowUserToDeleteRows = false;
this.AllowUserToOrderColumns = true;
this.AllowUserToResizeColumns = true;
this.AllowUserToResizeRows = false;
//设置行高
this.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
this.ColumnHeadersHeight = 50;
this.RowTemplate.Height = 45;
//美化标题
this.EnableHeadersVisualStyles = false;
this.ColumnHeadersDefaultCellStyle = new DataGridViewCellStyle()
{
WrapMode = DataGridViewTriState.True,
Alignment = DataGridViewContentAlignment.MiddleCenter,
BackColor = bc,
Padding = new Padding(0),
Font = new Font("微软雅黑", 15, FontStyle.Bold),
ForeColor = Color.White,
//SelectionBackColor= bc,
//SelectionForeColor= Color.White,
};
//美化单元格
this.DefaultCellStyle = new DataGridViewCellStyle()
{
WrapMode = DataGridViewTriState.False,
BackColor = bc2,
Padding = new Padding(0),
Font = new Font("微软雅黑", 15),
ForeColor = Color.Black,
SelectionBackColor = Draw.ColorChange(bc2, -0.1f),
SelectionForeColor = Color.Black,
};
}
bool isNum = true;
/// <summary>
/// 是否显示序号列
/// </summary>
[Browsable(true), Description("是否显示序号列")]
public bool IsNum
{
get => isNum;
set
{
if (this.DesignMode)
isNum = value;
else
{
var numColumn = this.Columns["number"];
if (numColumn == null)
{
this.Columns.Add("number", "序号");
numColumn = this.Columns["number"];
numColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
numColumn.MinimumWidth = 40;
numColumn.Width = 50;
numColumn.FillWeight = 50;
numColumn.DisplayIndex = 0;
}
isNum = value;
numColumn.Visible = value;
}
}
}
Type DataSourceTopType = null;
/// <summary>
/// 显示数据的数据源
/// </summary>
public new object DataSource
{
get => base.DataSource;
set
{
base.DataSource = value;
//类型发生改变:反射查找标题信息参数
if (DataSourceTopType == null || (!DataSourceTopType.IsAssignableFrom(value.GetType()) && value != null))
{
//需要隐藏的列
Dictionary<string, DataGridColumnAttribute> kv = new Dictionary<string, DataGridColumnAttribute>();
//泛型集合取第一个
var t = value.GetType();
if (t.IsGenericType)
{
Type[] ts = t.GetGenericArguments();
if (ts != null || ts.Length > 0)
t = ts[0];
}
//类上面的标注
var classIsShow = true;
var atts = t.GetCustomAttributes(typeof(DataGridColumnAttribute), false);
if (atts != null && atts.Length > 0)
{
var att = ((DataGridColumnAttribute[])atts)[0];
classIsShow = att.IsShow;
}
//属性上面的标注
var properties = t.GetProperties();
foreach (var property in properties)
{
atts = property.GetCustomAttributes(typeof(DataGridColumnAttribute), false);
if (atts != null && atts.Length > 0)
{
var att = ((DataGridColumnAttribute[])atts)[0];
kv.Add(property.Name, att);
}
else if (!classIsShow)
{
kv.Add(property.Name, new DataGridColumnAttribute(false));
}
}
if (kv.Any())
{
foreach (DataGridViewColumn dataGridViewColumn in this.Columns)
{
if (kv.TryGetValue(dataGridViewColumn.Name, out DataGridColumnAttribute att))
{
dataGridViewColumn.Visible = att.IsShow;
if (att.IsShow)
dataGridViewColumn.HeaderText = att.Name;
}
}
}
}
DataSourceTopType = value?.GetType();
}
}
private void DataGridViewBlue_CellClick(object sender, DataGridViewCellEventArgs e)
{
//点击单元格里面的按钮触发事件...
if (e.RowIndex >= 0)
{
var buttonText = this.Rows[e.RowIndex].Cells[e.ColumnIndex];
if (buttonText.OwningColumn.CellType.IsAssignableFrom(typeof(DataGridViewButtonCell)))
{
var cellData = this.Rows[e.RowIndex].DataBoundItem;
if (buttonText.OwningColumn.Name == "edit")
{
if (CellButtonClick != null)
CellButtonClick(sender, new DataGridViewCellButtonEventArgs(e, cellData, true, false, false));
}
else if (buttonText.OwningColumn.Name == "del")
{
if (CellButtonClick != null)
CellButtonClick(sender, new DataGridViewCellButtonEventArgs(e, cellData, false, true, false));
}
else
{
if (CellButtonClick != null)
CellButtonClick(sender, new DataGridViewCellButtonEventArgs(e, cellData, false, false, true, buttonText.OwningColumn.Name));
}
}
}
}
private void DataGridViewBlue_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
//自动加载序号列
if (IsNum)
foreach (DataGridViewRow row in this.Rows)
{
row.Cells["number"].Value = row.Index + 1;
}
}
}
public class DataGridViewCellButtonEventArgs : DataGridViewCellEventArgs
{
public DataGridViewCellButtonEventArgs(DataGridViewCellEventArgs dataGridViewCellEventArgs, object cellData, bool isEdit, bool isDel, bool isUc, string ucName = "") : base(dataGridViewCellEventArgs.ColumnIndex, dataGridViewCellEventArgs.RowIndex)
{
CellData = cellData;
IsEdit = isEdit;
IsDel = isDel;
IsUc = isUc;
UcName = ucName;
}
public DataGridViewCellButtonEventArgs(int columnIndex, int rowIndex, object cellData, bool isEdit, bool isDel, bool isUc, string ucName = "") : base(columnIndex, rowIndex)
{
CellData = cellData;
IsEdit = isEdit;
IsDel = isDel;
IsUc = isUc;
UcName = ucName;
}
/// <summary>
/// 单元格数据
/// </summary>
public object CellData { get; }
/// <summary>
/// 是否点击的编辑按钮
/// </summary>
public bool IsEdit { get; }
/// <summary>
/// 是否点击的删除按钮
/// </summary>
public bool IsDel { get; }
/// <summary>
/// 是否点击的自定义按钮
/// </summary>
public bool IsUc { get; }
/// <summary>
/// 点击的自定义按钮名称
/// </summary>
public string UcName { get; }
}
}
新建文件 DataGridColumnAttribute.cs
拷贝如下代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IntergratedTestTooling.Db.Models
{
/// <summary>
/// 对控件“dataGridView”“dataGrid”的列的标注信息
/// </summary>
public class DataGridColumnAttribute : Attribute
{
/// <summary>
/// 是否显示列
/// </summary>
public bool IsShow { get; set; } = true;
/// <summary>
/// 列名
/// </summary>
public string Name { get; set; } = string.Empty;
/// <summary>
/// 初始化对控件“dataGridView”“dataGrid”的列的标注信息
/// </summary>
public DataGridColumnAttribute()
{
}
/// <summary>
/// 初始化对控件“dataGridView”“dataGrid”的列的标注信息
/// </summary>
/// <param name="name">列名</param>
public DataGridColumnAttribute(string name)
{
Name = name;
}
/// <summary>
/// 初始化对控件“dataGridView”“dataGrid”的列的标注信息
/// </summary>
/// <param name="isShow">是否显示列</param>
public DataGridColumnAttribute(bool isShow)
{
IsShow = isShow;
}
}
}
新建文件 DataGridViewButtonUcColumn.cs
拷贝如下代码
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace IntergratedTestTooling
{
/// <summary>
/// 自定义的button列
/// </summary>
public class DataGridViewButtonUcColumn
{
public static Color bc = Color.FromArgb(0, 102, 153);//深蓝色
/// <summary>
/// 得到列对象(编辑)
/// </summary>
public static DataGridViewButtonColumn GetEditButtonColumn()
{
return new DataGridViewButtonColumn()
{
HeaderText = "",
MinimumWidth = 50,
Width = 60,
FillWeight = 60,
Name = "edit",
Text = "编辑",
UseColumnTextForButtonValue = true,
FlatStyle = FlatStyle.Flat,
//DisplayIndex = 998,
DefaultCellStyle = new DataGridViewCellStyle()
{
Alignment = DataGridViewContentAlignment.MiddleCenter,
Padding = new Padding(4, 2, 4, 2),
ForeColor = bc,
},
};
}
/// <summary>
/// 得到列对象(删除)
/// </summary>
public static DataGridViewButtonColumn GetDelButtonColumn()
{
return new DataGridViewButtonColumn()
{
HeaderText = "",
MinimumWidth = 50,
Width = 60,
FillWeight = 60,
Name = "del",
Text = "删除",
UseColumnTextForButtonValue = true,
FlatStyle = FlatStyle.Flat,
//DisplayIndex = 999,
DefaultCellStyle = new DataGridViewCellStyle()
{
Alignment = DataGridViewContentAlignment.MiddleCenter,
Padding = new Padding(4, 2, 4, 2),
ForeColor = Color.Red,
},
};
}
/// <summary>
/// 得到列对象(自定义)
/// </summary>
public static DataGridViewButtonColumn GetUcButtonColumn(string text = "详情", int width = 60, string name = "ucxq")
{
return new DataGridViewButtonColumn()
{
HeaderText = "",
MinimumWidth = 50,
Width = width,
FillWeight = width,
Name = name,
Text = text,
UseColumnTextForButtonValue = true,
FlatStyle = FlatStyle.Flat,
//DisplayIndex = 997,
DefaultCellStyle = new DataGridViewCellStyle()
{
Alignment = DataGridViewContentAlignment.MiddleCenter,
Padding = new Padding(4, 2, 4, 2),
ForeColor = bc,
},
};
}
}
}
使用方法:
1.对类进行标注或隐藏
public class GetLinePageDto
{
[DataGridColumn(false)]
public string Id { get; set; }
[DataGridColumn("城市名")]
public string CityName { get; set; }
[DataGridColumn("名称")]
public string Name { get; set; }
}
2.对内容进行绑定并增加2个按钮
private void UcTabLine_Load(object sender, EventArgs e)
{
dataGridViewBlue1.DataSource = new List<GetLinePageDto>();
dataGridViewBlue1.Columns.Add(DataGridViewButtonUcColumn.GetEditButtonColumn());
dataGridViewBlue1.Columns.Add(DataGridViewButtonUcColumn.GetDelButtonColumn());
if (!this.DesignMode)
UpdateDataUi();//更新表格
}
//点击单元格里面的按钮...
private void dataGridViewBlue1_CellButtonClick(object sender, DataGridViewCellButtonEventArgs e)
{
GetLinePageDto getLinePageDto = (GetLinePageDto)e.CellData;
if (e.IsDel)
{
if (Message.Show("确认删除吗?", "提示", MessageBoxButtons.OKCancel) == DialogResult.OK)
{
//1.执行数据库删除
//2.更新表格
UpdateDataUi();
}
}
else if (e.IsEdit)
{
}
}
3.页面的效果
