LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

C# DataGridView数据表格开发编辑

admin
2026年1月21日 22:6 本文热度 972
序言

WinForm数据展示需要用到的控件就是DataGridView,DataGridView这个"看似简单,实则复杂"的控件给无数C#开发者带来不小的困扰。 有时候想用却不知道怎么用,接下来就一步一步把这个控件的属性和方法研究明白。

正文:

一、核心属性

// 数据源绑定 - 你的数据展示基础DataSource: 支持DataTableDataSetList<T>等多种数据源// 自动列生成控制 - 避免列显示混乱的关键AutoGenerateColumnsfalse // 强烈建议手动控制列// 用户操作权限控制ReadOnlytrue/false // 是否允许编辑AllowUserToAddRowsfalse // 是否允许用户添加行AllowUserToDeleteRowsfalse // 是否允许用户删除行// 选择模式设置SelectionModeFullRowSelect // 整行选择,用户体验更好

二、操作方法

// 列操作三件套dataGridView.Columns.Add()    // 添加列dataGridView.Columns.Remove() // 移除列  dataGridView.Columns.Clear()  // 清空所有列// 数据刷新dataGridView.Refresh()        // 手动刷新显示

了解了上面的属性和方法以后,就可以开始测试使用了,下面看一个简单的用法;

namespace AccessOperate{
    public partial class DgvDisplay : Form    {        public DgvDisplay()        {            InitializeComponent();            // 创建DataGridView实例            DataGridView dgv = new DataGridView();            this.Controls.Add(dgv);
            //关键配置:阻止自动生成列            dgv.AutoGenerateColumns = false;            dgv.AllowUserToAddRows = false;            dgv.Dock = DockStyle.Fill;            dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            // 步骤3:手动创建列(避免显示混乱)            CreateColumns(dgv);
            // 步骤4:绑定数据源            BindData(dgv);

        }        private void CreateColumns(DataGridView dgv)        {            // 姓名列            var nameColumn = new DataGridViewTextBoxColumn            {                DataPropertyName = "Name"// 🎯 必须与模型属性名一致                HeaderText = "姓名",                AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill            };            dgv.Columns.Add(nameColumn);
            // 年龄列            var ageColumn = new DataGridViewTextBoxColumn            {                DataPropertyName = "Age",                HeaderText = "年龄",                Width = 80            };            dgv.Columns.Add(ageColumn);
            // 城市列            var cityColumn = new DataGridViewTextBoxColumn            {                DataPropertyName = "City",                HeaderText = "城市",                AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill            };            dgv.Columns.Add(cityColumn);        }        private void BindData(DataGridView dgv)        {            var people = new List<Person>            {                new Person { Name = "雷军", Age = 28, City = "北京" },                new Person { Name = "马云", Age = 35, City = "杭州" },                new Person { Name = "马化腾", Age = 42, City = "广州" }            };            //数据绑定            dgv.DataSource = people;        }    }    public class Person    {        public string Name { getset; }        public int Age { getset; }        public string City { getset; }    }}
很简单,就创建一个空白的WinForm窗体,不用往里面添加DataGridView控件,这里是在用程序添加的,this.Controls.Add(dgv);

运行完就可以显示数据了;

知识点:
1.DataPropertyName必须与模型属性名完全一致
2.设置AutoGenerateColumns = false避免列重复
3.使用AutoSizeMode.Fill让列自适应宽度

到这里我们就基本会使用DataGridView了,不过有时候数据不会这么简单,有时候要做的刷新和数据表的编辑,这样就需要下一定功夫了,下面接着看怎么操作;
namespace AccessOperate{
    public partial class DgvDisplay : Form    {        //数据源        private List<Person> people;        public DgvDisplay()        {            InitializeComponent();            InitializeForm();            LoadSampleData();
        }        private void InitializeForm()        {            //开启编辑模式的正确姿势            dgv_Display.ReadOnly = false;
            //注册数据变更事件            dgv_Display.CellValueChanged += OnCellValueChanged;
            //关键:确保编辑完成后触发事件            dgv_Display.CellEndEdit += OnCellEndEdit;
            //单元格开始编辑事件            dgv_Display.CellBeginEdit += OnCellBeginEdit;
            //数据错误处理            dgv_Display.DataError += OnDataError;
            // 行删除事件            dgv_Display.UserDeletingRow += OnUserDeletingRow;        }        private void LoadSampleData()        {            //初始化示例数据            people = new List<Person>            {                new Person { Name = "雷军", Age = 25, City = "北京", Email = "leijun@email.com", CreateDate = DateTime.Now.AddDays(-10) },                new Person { Name = "马云", Age = 30, City = "杭州", Email = "mayun@email.com", CreateDate = DateTime.Now.AddDays(-5) },                new Person { Name = "马化腾", Age = 28, City = "广州", Email = "mahuateng@email.com", CreateDate = DateTime.Now.AddDays(-3) },                new Person { Name = "王传福", Age = 35, City = "深圳", Email = "wangchuanfu@email.com", CreateDate = DateTime.Now.AddDays(-1) }            };            // 绑定数据源            dgv_Display.DataSource = people;
            //列设置优化            SetupColumns();        }        private void SetupColumns()        {            if (dgv_Display.Columns.Count > 0)            {                // 设置列标题                dgv_Display.Columns["Name"].HeaderText = "姓名";                dgv_Display.Columns["Age"].HeaderText = "年龄";                dgv_Display.Columns["City"].HeaderText = "城市";                dgv_Display.Columns["Email"].HeaderText = "邮箱";                dgv_Display.Columns["CreateDate"].HeaderText = "创建时间";
                // 设置列宽比例                dgv_Display.Columns["Name"].FillWeight = 20;                dgv_Display.Columns["Age"].FillWeight = 15;                dgv_Display.Columns["City"].FillWeight = 20;                dgv_Display.Columns["Email"].FillWeight = 25;                dgv_Display.Columns["CreateDate"].FillWeight = 20;
                // 设置创建时间为只读                dgv_Display.Columns["CreateDate"].ReadOnly = true;
                // 年龄列只允许数字                dgv_Display.Columns["Age"].ValueType = typeof(int);            }        }        //核心事件处理方法        private void OnCellValueChanged(object sender, DataGridViewCellEventArgs e)        {            if (e.RowIndex < 0return// 避免标题行触发事件
            var dgv = sender as DataGridView;            if (dgv.DataSource is List<Person> people && e.RowIndex < people.Count)            {                // 获取被修改的对象                Person updatedPerson = people[e.RowIndex];
                //实战应用:这里可以调用业务逻辑                SavePersonToDatabase(updatedPerson);
                // 更新状态栏或给用户反馈                this.Text = $"可编辑数据表格 - 已更新:{updatedPerson.Name} 的信息 [{DateTime.Now:HH:mm:ss}]";            }        }
        private void OnCellEndEdit(object sender, DataGridViewCellEventArgs e)        {            // 确保数据验证和格式化            var dgv = sender as DataGridView;            var cell = dgv[e.ColumnIndex, e.RowIndex];
            string columnName = dgv.Columns[e.ColumnIndex].Name;
            switch (columnName)            {                case "Age":                    // 年龄列数据验证                    if (!int.TryParse(cell.Value?.ToString(), out int age) || age < 0 || age > 150)                    {                        MessageBox.Show("请输入有效的年龄(0-150)!""数据验证", MessageBoxButtons.OK, MessageBoxIcon.Warning);                        cell.Value = 0// 设置默认值                    }                    break;
                case "Email":                    // 邮箱格式验证                    string email = cell.Value?.ToString();                    if (!string.IsNullOrEmpty(email) && !IsValidEmail(email))                    {                        MessageBox.Show("请输入有效的邮箱格式!""数据验证", MessageBoxButtons.OK, MessageBoxIcon.Warning);                        cell.Value = ""// 清空无效邮箱                    }                    break;
                case "Name":                    // 姓名不能为空                    if (string.IsNullOrWhiteSpace(cell.Value?.ToString()))                    {                        MessageBox.Show("姓名不能为空!""数据验证", MessageBoxButtons.OK, MessageBoxIcon.Warning);                        cell.Value = "未命名";                    }                    break;            }        }
        private void OnCellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)        {            // 可以在这里添加编辑前的逻辑            var dgv = sender as DataGridView;            string columnName = dgv.Columns[e.ColumnIndex].Name;
            // 例如:某些条件下禁止编辑            if (columnName == "CreateDate")            {                e.Cancel = true// 取消编辑                MessageBox.Show("创建时间不可编辑!""提示", MessageBoxButtons.OK, MessageBoxIcon.Information);            }        }        private void OnDataError(object sender, DataGridViewDataErrorEventArgs e)        {            // 处理数据类型转换错误等            MessageBox.Show($"数据错误:{e.Exception.Message}""错误", MessageBoxButtons.OK, MessageBoxIcon.Error);            e.Cancel = true;        }        private void OnUserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)        {            // 删除行前的确认            if (MessageBox.Show("确定要删除这条记录吗?""确认删除",                MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)            {                e.Cancel = true// 取消删除            }        }        //辅助方法        private void RefreshDataSource()        {            dgv_Display.DataSource = null;            dgv_Display.DataSource = people;            SetupColumns();        }        private bool IsValidEmail(string email)        {            try            {                var addr = new System.Net.Mail.MailAddress(email);                return addr.Address == email;            }            catch            {                return false;            }        }        private void SavePersonToDatabase(Person person)        {            try            {                // 这里实现你的数据保存逻辑                // 可以是数据库更新、API调用等                Console.WriteLine($"保存数据:{person.Name}{person.Age}{person.City}{person.Email}");
                // 模拟异步保存                Task.Run(() => {                    System.Threading.Thread.Sleep(100); // 模拟网络延迟                    // 实际保存到数据库的代码                });
            }            catch (Exception ex)            {                MessageBox.Show($"保存失败:{ex.Message}""错误", MessageBoxButtons.OK, MessageBoxIcon.Error);            }        }
        private void BtnAdd_Click(object sender, EventArgs e)        {            // 添加新记录            people.Add(new Person            {                Name = "新用户",                Age = 30,                City = "上海",                Email = "new@email.com",                CreateDate = DateTime.Now            });
            // 刷新数据源            RefreshDataSource();        }
        private void BtnDelete_Click(object sender, EventArgs e)        {            // 删除选中行            if (dgv_Display.SelectedRows.Count > 0)            {                var selectedIndex = dgv_Display.SelectedRows[0].Index;                if (selectedIndex < people.Count)                {                    if (MessageBox.Show("确定要删除选中的记录吗?""确认删除",                        MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)                    {                        people.RemoveAt(selectedIndex);                        RefreshDataSource();                    }                }            }            else            {                MessageBox.Show("请先选择要删除的行!""提示", MessageBoxButtons.OK, MessageBoxIcon.Information);            }        }
        private void BtnSaveAll_Click(object sender, EventArgs e)        {            // 保存所有数据            try            {                foreach (var person in people)                {                    SavePersonToDatabase(person);                }                MessageBox.Show($"成功保存 {people.Count} 条记录!""保存成功",                    MessageBoxButtons.OK, MessageBoxIcon.Information);            }            catch (Exception ex)            {                MessageBox.Show($"批量保存失败:{ex.Message}""错误", MessageBoxButtons.OK, MessageBoxIcon.Error);            }        }
        private void DgvDisplay_FormClosed(object sender, FormClosedEventArgs e)        {            // 取消事件订阅,避免内存泄漏            if (dgv_Display != null)            {                dgv_Display.CellValueChanged -= OnCellValueChanged;                dgv_Display.CellEndEdit -= OnCellEndEdit;                dgv_Display.CellBeginEdit -= OnCellBeginEdit;                dgv_Display.DataError -= OnDataError;                dgv_Display.UserDeletingRow -= OnUserDeletingRow;            }        }    }
    public class Person    {        public string Name { getset; }        public int Age { getset; }        public string City { getset; }        public string Email { getset; }        public DateTime CreateDate { getset; }    }}
WinForm上面添加按钮和DGV控件:
运行效果:
知识点:
1.同时监听CellValueChanged和CellEndEdit事件
2.做好数据验证,避免无效数据
3.提供用户反馈,提升体验

总结:

DataGridView虽然功能强大,但掌握了正确的使用方法,它就会成为你开发WinForm应用的得力助手。实践是最好的老师初学者朋友建议大家把这些代码在自己的项目中跑一遍,相信会有更深的理解。DataGridView控件还能绑定数据源,操作数据库文件,这些在后面慢慢掌握。


阅读原文:原文链接


该文章在 2026/1/22 13:20:01 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved