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.頁面的效果

