Winform控件基础之封装一个通用的DataGridView 操作类
1、创建Winform项目
2、创建公共控件操作文件夹
这里我们把公共的各种控件通用操作方法都提出出来放在这个文件夹下,方便调用。然后创建一个 DataGridViewHelper 类,如下所示:
3、主界面
1、控件布局
按照下图所示在主窗体上放置两个 dataGridView 控件,两个按钮。
代码实现:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WinformCommonDemo.CommControlOperate;
using WinformCommonDemo.DataModel;
namespace WinformCommonDemo
{
public partial class MainUI : Form
{
public MainUI()
{
InitializeComponent();
}
private void my_DataGridView_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (my_DataGridView.Rows.Count > 0)
{
if (my_DataGridView.CurrentCell.Value.ToString() == "删除")
{
DataGridViewHelper.DelSingleDataGridView<DataListModel>(my_DataGridView);
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
//列表样式初始化
InitDataGridView();
}
private void LoadDataList()
{
string path = Path.Combine(Directory.GetCurrentDirectory(), "DataList.txt");
string json = TxtOperateHelper.ReadTxt(path);
List<DataListModel> list = new List<DataListModel>();
list = json.ToObj<List<DataListModel>>();
if (list.Count > 0)
{
//初始化
DataGridViewHelper.BindDataGridView(my_DataGridView, list);
DataGridViewHelper.BindDataGridView(dataGridView1, list);
}
}
private void InitDataGridView()
{
string path = Path.Combine(Directory.GetCurrentDirectory(), "DataGridViewData.txt");
string json = TxtOperateHelper.ReadTxt(path);
List<DataGridViewModel> list = new List<DataGridViewModel>();
list = json.ToObj<List<DataGridViewModel>>();
if (list.Count > 0)
{
//初始化
DataGridViewHelper.InitDataGridView(my_DataGridView, list);
DataGridViewHelper.InitDataGridView(dataGridView1, list);
}
}
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (dataGridView1.Rows.Count > 0)
{
if (dataGridView1.CurrentCell.Value.ToString() == "删除")
{
DataGridViewHelper.DelSingleDataGridView<DataListModel>(dataGridView1);
}
}
}
private void button1_Click(object sender, EventArgs e)
{
List<DataListModel> datas = DataGridViewHelper.SaveDataGridView<DataListModel>(my_DataGridView);
if (datas.Count > 0)
{
//这里将数据集 datas 转存到需要的数据库即可;
MessageBox.Show("数据保存成功", "提示", MessageBoxButtons.OK);
}
else
{
MessageBox.Show("暂无要保存的数据", "提示", MessageBoxButtons.OK);
}
}
private void button2_Click(object sender, EventArgs e)
{
DataGridViewHelper.ClearDataGridView(my_DataGridView);
}
private void button3_Click(object sender, EventArgs e)
{
//加载数据
LoadDataList();
}
}
}
2、提取通用方法
我们对dataGridView 进行了一些功能归纳,主要有以下几个功能:
- 表初始化(InitDataGridView) 主要实现表标题名、颜色、文字等表格样式的初始化;
- 数据绑定(BindDataGridView) 主要用来显示需要展示的数据
- 数据编辑 主要用来实现表格数据编辑、修改,这里直接双击单元列就可以修改
- 数据删除(DelSingleDataGridView) 主要用来删除表格选中行数据
- 数据保存(SaveDataGridView) 主要用来保存表格中修改的数据
- 数据清空(ClearDataGridView) 主要用来清空表格数据
3、静态方法类实现
在 DataGridViewHelper 中分别实现通用方法如下所示:
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WinformCommonDemo.DataModel;
namespace WinformCommonDemo.CommControlOperate
{
public class DataGridViewHelper
{
/// <summary>
/// 表结构初始化
/// </summary>
/// <param name="dataGridView">控件名称</param>
/// <param name="ColumnModel">结构模型集合</param>
public static void InitDataGridView(DataGridView dataGridView, List<DataGridViewModel> ColumnModel)
{
dataGridView.AutoGenerateColumns = false; //禁止自动创建列
dataGridView.AllowUserToAddRows = false; //禁止自动添加行
dataGridView.AllowUserToOrderColumns = false; //禁止排序
dataGridView.AllowUserToResizeColumns = false; //禁止列宽大小变化
dataGridView.AllowUserToResizeRows = false; //禁止行高大小变化
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;//表头高度自适应
dataGridView.RowHeadersVisible = false; //隐藏表空白首列
dataGridView.Columns.Clear();
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect; //是选中模式为单行整行选中
dataGridView.BackgroundColor = dataGridView.Parent.BackColor; //设置表格背景颜色与父容器颜色一致
for (int i = 0; i < ColumnModel.Count; i++)
{
DataGridViewColumn fColumn;
switch (ColumnModel[i].ColumnType)
{
case ColumnType.Link:
fColumn = new DataGridViewColumn(new DataGridViewLinkCell());
break;
case ColumnType.Button:
fColumn = new DataGridViewColumn(new DataGridViewButtonCell());
break;
case ColumnType.Image:
fColumn = new DataGridViewColumn(new DataGridViewImageCell());
break;
case ColumnType.Combox:
fColumn = new DataGridViewColumn(new DataGridViewComboBoxCell());
break;
case ColumnType.CheckBox:
fColumn = new DataGridViewColumn(new DataGridViewCheckBoxCell());
break;
default:
fColumn = new DataGridViewColumn(new DataGridViewTextBoxCell());
break;
}
fColumn.HeaderText = ColumnModel[i].DisplayName;
fColumn.DataPropertyName = ColumnModel[i].PropertyName;
fColumn.Width = ColumnModel[i].Width;
fColumn.ReadOnly = ColumnModel[i].ReadOnly;
fColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
//如果该单元格支持编辑修改,让背景色与其他单元格有区分
if (!ColumnModel[i].ReadOnly)
{
fColumn.CellTemplate.Style.BackColor = Color.DarkGray;
}
// 这里改变 Add 顺序将会决定列显示顺序
dataGridView.Columns.Add(fColumn);
}
// 设置所有列的标题行居中对齐
foreach (DataGridViewColumn column in dataGridView.Columns)
{
column.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
}
}
/// <summary>
/// 数据绑定
/// </summary>
/// <param name="dataGridView">控件名称</param>
/// <param name="gridViewList">数据集合</param>
public static void BindDataGridView<T>(DataGridView dataGridView, List<T> gridViewList)
{
if (gridViewList.Count > 0)
{
dataGridView.DataSource = gridViewList;
dataGridView.Height = dataGridView.Rows.Count * dataGridView.RowTemplate.Height + dataGridView.ColumnHeadersHeight;
}
else
{
dataGridView.DataSource = gridViewList;
dataGridView.Height = 60;
}
}
public static void DelSingleDataGridView<T>(DataGridView dataGridView)
{
List<T> list = new List<T>();
// 检查是否有当前选中的单元格
if (dataGridView.CurrentCell != null)
{
// 获取当前选中单元格所在的行
DataGridViewRow currentRow = dataGridView.CurrentCell.OwningRow;
foreach (DataGridViewRow row in dataGridView.Rows)
{
if (row.Index != currentRow.Index)
{
T dataModel = (T)row.DataBoundItem;
list.Add(dataModel);
}
}
dataGridView.DataSource = list;
}
}
public static List<T> SaveDataGridView<T>(DataGridView dataGridView)
{
List<T> list = new List<T>();
if (dataGridView.Rows.Count > 0)
{
foreach (DataGridViewRow row in dataGridView.Rows)
{
T dataModel = (T)row.DataBoundItem;
list.Add(dataModel);
}
}
return list;
}
/// <summary>
/// 清空表结构
/// </summary>
/// <param name="dataGridView"></param>
public static void ClearDataGridView(DataGridView dataGridView)
{
dataGridView.DataSource = null;
}
}
}
4、其他工具类实现
1、JsonHelper 工具类实现
主要用来实现 Json格式的序列化和对象转换,代码实现如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
namespace WinformCommonDemo.CommControlOperate
{
public static class JsonHelper
{
static JavaScriptSerializer js = new JavaScriptSerializer();
public static string ToJson(this object obj)
{
try
{
return js.Serialize(obj);
}
catch (Exception e)
{
return null;
}
}
public static T ToObj<T>(this string json)
{
try
{
return js.Deserialize<T>(json);
}
catch (Exception e)
{
return default(T);
}
}
}
}
2、TxtOperateHelper工具类实现
主要用来实现 txt 文档读取操作
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WinformCommonDemo.CommControlOperate
{
public class TxtOperateHelper
{
public static string ReadTxt(string path)
{
string[] lines = File.ReadAllLines(path);
string resulyStr=string.Empty;
foreach (string line in lines)
{
resulyStr += line;
}
return resulyStr;
}
}
}
5、数据模型实现
这里我们先创建一个 DataModel 文件夹,主要用来存放程序中各种数据模型
1、创建表结构模型
在DataModel 文件夹下创建 DataGridViewModel.cs 类,该模型主要定义了 DataGridView 表的内部常用属性字段,也可以根据自己的需求取拓展和更改,代码结构如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WinformCommonDemo.DataModel
{
public class DataGridViewModel
{
/// <summary>
/// 属性名称
/// </summary>
public string PropertyName { get; set; }
/// <summary>
/// 显示名称
/// </summary>
public string DisplayName { get; set; }
/// <summary>
/// 单元格控件类型
/// </summary>
public ColumnType ColumnType { get; set; }
/// <summary>
/// 列宽
/// </summary>
public int Width { get; set; }
/// <summary>
/// 读写状态 true 不可编辑 false 可编辑
/// </summary>
public bool ReadOnly { get; set; }
}
public enum ColumnType
{
TextBox,
Button,
Image,
Combox,
CheckBox,
Link
}
}
2、创建表数据模型
创建一个 DataListModel.cs 数据模型类,该模型主要用来组装数据集合,最终将数据显示到表格,模型结构如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WinformCommonDemo.DataModel
{
public class DataListModel
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Gender { get; set; }
public string Tel { get; set; }
public string City { get; set; }
public string ClassName { get; set; }
public string OperateName { get; set; }
}
}
6、案例数据
创建一个 TestData 文件夹,用来存放案例的测试数据,数据均为 txt 文件,内部数据格式满足 Json 数据格式。
1、表结构数据集
创建 DataGridViewData.txt 文件,文件内容如下:
[{
"DisplayName": "序号",
"PropertyName": "Id",
"ColumnType": 0,
"Width": 30,
"ReadOnly": "true"
},
{
"DisplayName": "姓名",
"PropertyName": "Name",
"ColumnType": 0,
"Width": 70,
"ReadOnly": "false"
},
{
"DisplayName": "年龄",
"PropertyName": "Age",
"ColumnType": 0,
"Width": 70,
"ReadOnly": "false"
},
{
"DisplayName": "性别",
"PropertyName": "Gender",
"ColumnType": 0,
"Width": 70,
"ReadOnly": "true"
},
{
"DisplayName": "电话",
"PropertyName": "Tel",
"ColumnType": 0,
"Width": 100,
"ReadOnly": "false"
},
{
"DisplayName": "城市",
"PropertyName": "City",
"ColumnType": 0,
"Width": 70,
"ReadOnly": "false"
},
{
"DisplayName": "班级",
"PropertyName": "ClassName",
"ColumnType": 0,
"Width": 70,
"ReadOnly": "false"
},
{
"DisplayName": "操作",
"PropertyName": "OperateName",
"ColumnType": 1,
"Width": 70,
"ReadOnly": "true"
}
]
2、表测试数据集
创建 DataList.txt 文件,文件内容如下:
[{
"Id": 1,
"Name": "张小三",
"Age": 6,
"Gender": "男",
"Tel": "17455890455",
"City": "成都",
"ClassName": "一年级",
"OperateName": "删除"
},
{
"Id": 2,
"Name": "李小四",
"Age": 8,
"Gender": "男",
"Tel": "17455890455",
"City": "成都",
"ClassName": "四年级",
"OperateName": "删除"
},
{
"Id": 3,
"Name": "王小五",
"Age": 8,
"Gender": "男",
"Tel": "17455890455",
"City": "成都",
"ClassName": "五年级",
"OperateName": "删除"
},
{
"Id": 4,
"Name": "赵小六",
"Age": 6,
"Gender": "男",
"Tel": "17455890455",
"City": "成都",
"ClassName": "一年级",
"OperateName": "删除"
},
{
"Id": 5,
"Name": "钱小七",
"Age": 8,
"Gender": "男",
"Tel": "17455890455",
"City": "成都",
"ClassName": "四年级",
"OperateName": "删除"
},
{
"Id": 6,
"Name": "孙小八",
"Age": 7,
"Gender": "男",
"Tel": "17455890455",
"City": "成都",
"ClassName": "三年级",
"OperateName": "删除"
},
{
"Id": 7,
"Name": "吴小九",
"Age": 5,
"Gender": "男",
"Tel": "17455890455",
"City": "成都",
"ClassName": "二年级",
"OperateName": "删除"
},
{
"Id": 8,
"Name": "丁小十",
"Age": 6,
"Gender": "男",
"Tel": "17455890455",
"City": "成都",
"ClassName": "二年级",
"OperateName": "删除"
}
]
7、案例运行注意事项
本案例全部源代码已经在上述步骤中全部展示,拷贝代码运行注意事项如下:
1、命名空间的不一致,本案例项目名称为 WinformCommonDemo,如果引用到自己项目中,注意修改命名空间。整个项目文件层级分布如下:
2、测试数据位置,本案例数据单独创建了 TestData文件存放,但实际运行时需要将两个 txt 数据文件存放在Debug或者 Release 文件夹下,这个取决于你的 VS 运行的模式。如下:
8、运行效果
9、源代码获取
1、CSDN 源码下载:Winform控件基础与进阶----DataGridView
2、资源搜索:https://cfpkae563ie2rxce6hafistkdzxd8gr.taobao.com/