当前位置:首页 » 《关注互联网》 » 正文

C#高级:Winform桌面开发中DataGridView的详解

26 人参与  2024年10月25日 12:01  分类 : 《关注互联网》  评论

点击全文阅读


目录

一、前端界面

二、模块代码

1.初始化列表代码

2.点击单元格按钮事件(datagridview双击进入)

3.一键选中(checkbox)双击进入

 4.查看选中(button)双击进入

5.点击按钮获取选中的一行实体

6.点击单元格获取实体

 7.点击单元行头获取实体

8.获取数据列表

9.列头居中对齐的方法

三、整体代码

四、测试结果

五、样式

六、高度封装的数据填充方法

七、高度封装的分页方法

八、小结


一、前端界面

添加的datagridview应该如下设置:

1.只设置启用编辑

2.设置好每列的名称、控件类型、提示中文(页眉文本),选择【可见】等选项(建议TextBox选可见+只读,Checkbox选可见即可,Button选可见即可。选择只读后,不能被编辑或选中。)

3.如果不需要默认列,可以设置:RowHeadersVisibed = False 

二、模块代码

【实体列表】

1.初始化列表代码

【备注】1.建立列表是模拟查数据库。2.“如果学生名为"小苏",则移除查看详情按钮”是一个题目要求,实际中不需要该功能可注释掉该代码。3.数据实体绑定于Tag上,Tag能识别哪行被点击或选中。

 /// <summary> /// 初始化填充数据 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form1_Load(object sender, EventArgs e) {     #region 建立列表     Student student1 = new Student { ID = 1, Name = "小苏", Remarks = "小苏的备注" };     Student student2 = new Student { ID = 2, Name = "小明", Remarks = "小明的备注" };     Student student3 = new Student { ID = 3, Name = "小花", Remarks = "小花的备注" };     var list = new List<Student>();     list.Add(student1);     list.Add(student2);     list.Add(student3);     #endregion     // 清空现有数据     dataGridView1.Rows.Clear();     //添加数据     foreach (var item in list)     {         int rowIndex = dataGridView1.Rows.Add();         dataGridView1.Rows[rowIndex].Cells["ID"].Value = item.ID;//字段         dataGridView1.Rows[rowIndex].Cells["StuName"].Value = item.Name;//字段         dataGridView1.Rows[rowIndex].Cells["Details"].Value = "查看详情";//按钮名称         dataGridView1.Rows[rowIndex].Tag = item;         // 如果学生名为"小苏",则移除查看详情按钮         if (item.Name == "小苏")         {             dataGridView1.Rows[rowIndex].Cells["Details"] = new DataGridViewTextBoxCell();//重新初始化             dataGridView1.Rows[rowIndex].Cells["Details"].ReadOnly = true;  // 设置为只读         }     } }

【扩展】也可以直接选择绑定而不写上述代码:(灵活性降低)

2.点击单元格按钮事件(datagridview双击进入)

作用:点击查看详情跳出备注信息

/// <summary>/// 点击查看详情/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e){    if (e.ColumnIndex == dataGridView1.Columns["Details"].Index && e.RowIndex >= 0)//若点击了标签为【Details】列的按钮    {        // 获取当前行对应的实体对象【注意修改此处Student类】,此处能获取到Remarks字段(虽然没有显示在界面上,但也绑定到Tag了)        var item = dataGridView1.Rows[e.RowIndex].Tag as Student;        //将list实体中的Remarks展示出来(item包含的字段:ID,Name,Remarks)        MessageBox.Show(item.Remarks, "内容详情");        //【补充一:获取按钮上的文字】    }}

【补充一:获取按钮上的文字】

DataGridViewButtonCell buttonCell = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex] as DataGridViewButtonCell;//获取点击的按钮if (buttonCell != null && buttonCell.Value != null){    if (buttonCell.Value.ToString() == "借出")//按钮字样为借出    {        ;// 执行借出操作    }    else if (buttonCell.Value.ToString() == "归还")//按钮字样为归还    {        ;// 执行归还操作    }}

3.一键选中(checkbox)双击进入

作用:点击一键选中按钮,选中列表所有的checkbox

/// <summary>/// 一键选中/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void checkBox1_CheckedChanged(object sender, EventArgs e){    if(checkBox1.Checked)    {        foreach (DataGridViewRow row in dataGridView1.Rows)        {            DataGridViewCheckBoxCell checkBox = row.Cells["ManySelect"] as DataGridViewCheckBoxCell;//获取【ManySelect】的checkbox列            if (checkBox != null)            {                checkBox.Value = true;            }        }    }}

 4.查看选中(button)双击进入

作用:点击查看选中按钮,获得一个选中的列表

方法一:

/// <summary>/// 点击查看选中/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void button1_Click(object sender, EventArgs e)//点击触发{    //获取【DataGridView1】的checkbox选中的实体    var selectlist = new List<Student>();//将【Student】类存放入列表    //遍历获取数据    foreach (DataGridViewRow row in dataGridView1.Rows)    {        DataGridViewCheckBoxCell checkBox = row.Cells["ManySelect"] as DataGridViewCheckBoxCell;        if (checkBox != null && checkBox.Value != null  && (bool)checkBox.Value)        {            // 获取与选中CheckBox相关联的实体,假设实体类型为Student            var entity = row.Tag as Student; //【Student】实体            if (entity != null)            {                selectlist.Add(entity);            }        }    }    //后续可对selectlist操作}

方法二:(获取单一内容)

private void button3_Click(object sender, EventArgs e){    // 创建一个列表来存储选中的内容    List<string> selectedContents = new List<string>();    // 遍历所有行    foreach (DataGridViewRow row in dataGridView1.Rows)    {        // 检查该行是否被选中        if (Convert.ToBoolean(row.Cells["Select"].Value) == true)        {            // 获取 "Content" 列的值,并添加到列表中            string contentValue = row.Cells["Content"].Value.ToString();            selectedContents.Add(contentValue);        }    }    // 显示选中的内容(可以根据需要进行其他处理)    MessageBox.Show(string.Join(", ", selectedContents));}

5.点击按钮获取选中的一行实体

前提条件:需要默认列,可以设置 RowHeadersVisibed = True ,即获取点击单元行头的实体

private void button3_Click(object sender, EventArgs e){    if (dataGridView2.SelectedRows.Count == 1)//当选中了一行时    {        // 获取选中的那行,转化为【StuMessage】实体        var selectedEntity = dataGridView2.Rows[dataGridView2.SelectedRows[0].Index].Tag as StuMessage;        ;    }}

6.点击单元格获取实体

private void dataGridView2_CellContentClick(object sender, DataGridViewCellEventArgs e){    var stumodel = dataGridView2.Rows[e.RowIndex].Tag as StuMessage;}

//如果单纯获取点击的内容:string clickedContent = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();

 7.点击单元行头获取实体

private void dataGridView2_RowHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e){    var stumodel = dataGridView2.Rows[e.RowIndex].Tag as StuMessage;}

8.获取数据列表

  封装方法

 /// <summary> /// 获取指定datagridview的列表,并转化为T实体 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="dataGridView"></param> /// <returns></returns> private List<T> GetDataGridList<T>(DataGridView dataGridView) where T : class {     List<T> list = new List<T>();     foreach (DataGridViewRow row in dataGridView.Rows)     {         var item = row.Tag as T;          list.Add(item);     }     return list; }

调用方法:请将Notice替换为您的实体

var list = GetDataGridList<Notice>(dataGridView1);

9.列头居中对齐的方法

三、整体代码

【注意】此代码为Demo代码,并不符合编写规范,旨在帮助开发者找到灵感。

using System.Collections.Generic;namespace WinFormsApp2{    public partial class Form1 : Form    {        public Form1()        {            InitializeComponent();        }        class Student        {            public int ID { get; set; }            public string Name { get; set; }            public string Remarks { get; set; }        }        /// <summary>        /// 初始化填充数据        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void Form1_Load(object sender, EventArgs e)        {            #region 建立列表            Student student1 = new Student { ID = 1, Name = "小苏", Remarks = "小苏的备注" };            Student student2 = new Student { ID = 2, Name = "小明", Remarks = "小明的备注" };            Student student3 = new Student { ID = 3, Name = "小花", Remarks = "小花的备注" };            var list = new List<Student>();            list.Add(student1);            list.Add(student2);            list.Add(student3);            #endregion            // 清空现有数据            dataGridView1.Rows.Clear();            //添加数据            foreach (var item in list)            {                int rowIndex = dataGridView1.Rows.Add();                dataGridView1.Rows[rowIndex].Cells["ID"].Value = item.ID;//字段                dataGridView1.Rows[rowIndex].Cells["StuName"].Value = item.Name;//字段                dataGridView1.Rows[rowIndex].Cells["Details"].Value = "查看详情";//按钮名称                dataGridView1.Rows[rowIndex].Tag = item;                // 如果学生名为"小苏",则移除查看详情按钮                if (item.Name == "小苏")                {                    dataGridView1.Rows[rowIndex].Cells["Details"] = new DataGridViewTextBoxCell();//重新初始化                    dataGridView1.Rows[rowIndex].Cells["Details"].ReadOnly = true;  // 设置为只读                }            }        }        /// <summary>        /// 点击查看选中        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void button1_Click(object sender, EventArgs e)//点击触发        {            //获取【DataGridView1】的checkbox选中的实体            var selectlist = new List<Student>();//将【Student】类存放入列表            //遍历获取数据            foreach (DataGridViewRow row in dataGridView1.Rows)            {                DataGridViewCheckBoxCell checkBox = row.Cells["ManySelect"] as DataGridViewCheckBoxCell;                if (checkBox != null && checkBox.Value != null  && (bool)checkBox.Value)                {                    // 获取与选中CheckBox相关联的实体,假设实体类型为Student                    var entity = row.Tag as Student; //【Student】实体                    if (entity != null)                    {                        selectlist.Add(entity);                    }                }            }            //后续可对selectlist操作        }        /// <summary>        /// 点击查看详情        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)        {            if (e.ColumnIndex == dataGridView1.Columns["Details"].Index && e.RowIndex >= 0)//若点击了标签为【Details】列的按钮            {                // 获取当前行对应的实体对象【注意修改此处Student类】,此处能获取到Remarks字段(虽然没有显示在界面上,但也绑定到Tag了)                var item = dataGridView1.Rows[e.RowIndex].Tag as Student;                //将list实体中的Remarks展示出来(item包含的对象:ID,Name,Remarks)                MessageBox.Show(item.Remarks, "内容详情");            }        }        /// <summary>        /// 一键选中        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void checkBox1_CheckedChanged(object sender, EventArgs e)        {            if(checkBox1.Checked)            {                foreach (DataGridViewRow row in dataGridView1.Rows)                {                    DataGridViewCheckBoxCell checkBox = row.Cells["ManySelect"] as DataGridViewCheckBoxCell;//获取【ManySelect】多选框列                    if (checkBox != null)                    {                        checkBox.Value = true;                    }                }            }        }    }}

四、测试结果

1.通过debug发现选中有效(测试通过)

2.发现小苏对应按钮被删除(测试通过)

3.发现一键多选奏效(测试通过,图略) 

4.发现查看详情有效(测试通过)

五、样式

修改某行的字体颜色:

if (item.Name == "小明"){    dataGridView1.Rows[rowIndex].DefaultCellStyle.ForeColor = Color.Red;//文字颜色    dataGridView1.Rows[rowIndex].DefaultCellStyle.BackColor = Color.Yellow;//背景颜色}

六、高度封装的数据填充方法

【封装方法】

 /// <summary> /// 获取DataGridView,需传入控件、数据列表、标题列表 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="dataGridView"></param> /// <param name="list"></param> /// <param name="headtext"></param> /// <exception cref="Exception"></exception> private void GetDataGridView<T>(DataGridView dataGridView,List<T> list,List<string> headtext)  where T : class {     //设置表头样式和属性     dataGridView.AllowUserToAddRows = false;//不允许添加、删除     dataGridView.AllowUserToDeleteRows = false;     dataGridView.ReadOnly = true;//设置可读     dataGridView.RowHeadersVisible = false;//隐藏最左边的空白栏     dataGridView.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;//表头居中对齐     dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;//自适应宽度     //dataGridView.RowTemplate.Height = 80;//设置行高     //获取字段列表     var field = typeof(T).GetProperties();     //判断输入标题     if (headtext.Count != field.Length)     {         throw new Exception("表头的标题个数要和字段长度一致!");     }    // 设置表头样式    dataGridView.ColumnHeadersDefaultCellStyle = new DataGridViewCellStyle    {        Alignment = DataGridViewContentAlignment.MiddleCenter, // 中间对齐        BackColor = Color.LightGray, // 表头背景色        ForeColor = Color.Black, // 表头文字颜色        Font = new Font("微软雅黑", 12F, FontStyle.Bold), // 表头字体    };     //设置表格内容(按实体顺序依次设置名字)     dataGridView.Columns.Clear();     foreach (var item in headtext)     {         dataGridView.Columns.Add(new DataGridViewTextBoxColumn  //增加文字列         {             DefaultCellStyle = new DataGridViewCellStyle { Alignment = DataGridViewContentAlignment.MiddleCenter },             HeaderText = item,//中文标题             MinimumWidth = 6,             Name = field[headtext.FindIndex(x=>x==item)].Name,//字段的名字 例如ID Name             ReadOnly = true,             SortMode = DataGridViewColumnSortMode.NotSortable,             Width = 110         });     }     //dataGridView.Columns.Add(new DataGridViewButtonColumn  //增加按钮     //{     //    DefaultCellStyle = new DataGridViewCellStyle { Alignment = DataGridViewContentAlignment.MiddleCenter },     //    HeaderText = "操作",//中文标题     //    MinimumWidth = 6,     //    Name = "btn1",//字段的名字 例如ID Name     //    ReadOnly = true,     //    SortMode = DataGridViewColumnSortMode.NotSortable,     //    Width = 110     //});    //dataGridView.Columns[0].Width = 200; // 手动调节宽度    //dataGridView.Columns[1].Width = 200; // 手动调节宽度    // dataGridView.Columns[2].Width = 80; // 手动调节宽度    // dataGridView.Columns[3].Width = 80; // 手动调节宽度    // dataGridView.Columns[4].Width = 80; // 手动调节宽度    // dataGridView.Columns[5].Width = 80; // 手动调节宽度    // dataGridView.Columns[6].Width = 300; // 手动调节宽度         // 清空现有数据     dataGridView.Rows.Clear();     //添加数据     foreach (var item in list)     {         int rowIndex = dataGridView.Rows.Add();         foreach (var jtem in field)         {             dataGridView.Rows[rowIndex].Cells[jtem.Name.ToString()].Value = jtem.GetValue(item);//字段             dataGridView.Rows[rowIndex].DefaultCellStyle.ForeColor = Color.Black;             //if (jtem.Name.ToString().Equals("time"))//对特定的字段处理             //{                   //dataGridView.Rows[rowIndex].Cells[jtem.Name.ToString()].Value = ((DateTime)(jtem.GetValue(item))).ToString("yyyy年MM月dd日");             //}             //dataGridView.Rows[rowIndex].Cells["btn1"].Value = "点击我";//按钮名称             //移除按钮(两步)             //if (false)             //{             //    dataGridView.Rows[rowIndex].Cells["btn1"] = new DataGridViewTextBoxCell();//重新初始化             //    dataGridView.Rows[rowIndex].Cells["btn1"].ReadOnly = true;  // 设置为只读             //}         }         dataGridView.Rows[rowIndex].Tag = item;//绑定到Tag上方便后续调用     } }

【调用示例】 

private void checkBox1_CheckedChanged(object sender, EventArgs e){    string sql = @"SELECT  types,time,objects  FROM BuyTable ";    var entity = new Notice();    //从数据库中获取列表存入list    var list = entity.QueryBySQL(sql);    //设置标题    var headtext = new List<string>() { "购买类型", "购买时间","购买物品" };    //获取dataGridView    GetDataGridView(dataGridView10,list, headtext);}

七、高度封装的分页方法

 /// <summary> /// 查询数据 /// </summary> private void GetData() {     var list = GetList().ToList();//假设这里是查表操作     list = GetPageList(list, label7, label6, button2, button3);//【步骤一】传入相关控件实现分页     List<string> title = new List<string> { { "开奖期数" }, { "开奖时间" }, { "平均值" }, { "最大值" }, { "最小值" }, { "跨度值" }, { "开奖号码" } };     GetDataGridView(dataGridView1, list, title);//渲染到DataGridView中 } private int currentIndex = 1; // 当前页索引 private int totalPages = 0; // 总页数 private List<T> GetPageList<T>(List<T> list, Label total, Label Pagedetails, Button lastpage, Button nextpage, int pagesize = 7) {     lastpage.Enabled = false;     nextpage.Enabled = false;     var count = list.Count;     totalPages = (count + pagesize - 1) / pagesize; // 计算总页数     if (Pagedetails.Text.Equals("第1页/共x页")) // 【 步骤二 winform默认设置好Pagedetails="第1页/共x页"】,此处代表第一次进入     {         currentIndex = 1; // 初始化当前页     }     else     {         // 创建正则表达式对象         Regex regex = new Regex(@"第(\d+)页/共(\d+)页");         // 尝试匹配字符串         Match match = regex.Match(Pagedetails.Text);         currentIndex = Convert.ToInt32(match.Groups[1].Value);     }     // 更新页数显示     Pagedetails.Text = $"第{currentIndex}页/共{totalPages}页";     total.Text = $"共{count}条数据";     // 更新按钮状态     lastpage.Enabled = currentIndex > 1; // 如果不是第一页,启用上一页按钮     nextpage.Enabled = currentIndex < totalPages; // 如果不是最后一页,启用下一页按钮     return list.Skip((currentIndex - 1) * pagesize).Take(pagesize).ToList(); // 获取当前页的数据 } //上一页(双击按钮订阅此事件) private void button2_Click(object sender, EventArgs e) {     if (currentIndex > 1) // 检查是否可以向前翻页     {         currentIndex--; // 当前页减一         label6.Text = $"第{currentIndex}页/共{totalPages}页";//【步骤三】更新 Pagedetails 标签         GetData();     } } //下一页(双击按钮订阅此事件) private void button3_Click(object sender, EventArgs e) {     if (currentIndex < totalPages) // 检查是否可以向后翻页     {         currentIndex++; // 当前页加一         label6.Text = $"第{currentIndex}页/共{totalPages}页";//【步骤三】更新 Pagedetails 标签         GetData();     } }

八、小结

1.增:  建议用textbox、combobox等工具增,而不是直接datagridview新增,一来代码编写麻烦,二来输入工具不能多样化(比如说时间控件、多选框控件)。

2.删:建议每条数据加一个删除按钮,方便操作

3.改:建议选中某条数据然后将数据信息转移到textbox上,label显示“您已选中xxx数据”,然后点击button去修改相应信息(选中数据和点击按钮都能获取到对应实体)

4.查:同第2条

5.如果单纯用datagridview作增删查改,虽然能实现,但是代码复杂难以维护,而且输入条件单一,容易操作失误,不建议这么做。


点击全文阅读


本文链接:http://zhangshiyu.com/post/177320.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1