WinForm DataGridView增删改操作实现详解

林舟
林舟
发布时间:2026-10-14| 6人浏览过
原创

在Windows Forms开发中,频繁需要处理列表型数据的增删改查。本文基于BindingList与BindingSource机制,详细演示如何在DataGridView中实现行的动态添加、点击行回填进行编辑修改,以及选中行删除的核心代码逻辑。

环境准备与数据模型

要实现DataGridView的动态数据展示,首先需要一个能够支持更改通知的集合类。IList<T>通常不直接支持双向绑定刷新,因此推荐配合BindingList<T>使用。

第1步:定义实体类

创建一个包含所需属性的结构体或类,例如SelfRun,用于存储运行配置信息:

public struct SelfRun
{
    public string OpCtuCh { get; set; }
    public string OpWay { get; set; }
    public int OpTime { get; set; }

    public SelfRun(string _opCtuCh, string _opWay, int _opTime)
        : this()
    {
        OpCtuCh = _opCtuCh;
        OpWay = _opWay;
        OpTime = _opTime;
    }
}

第2步:初始化绑定源

将自定义的实体列表包装为BindingList并赋值给BindingSource,最后绑定到DataGridView:

IList<SelfRun> selfRunConfigs = new List<SelfRun&gt();

private void BindGridViewForIList<T>(DataGridView gv, IList<T> datasource)
{
    BindingList<T> bindinglist = new BindingList<T>(datasource);
    BindingSource source = new BindingSource(bindinglist, null);
    gv.DataSource = source;
}

添加新行数据

添加操作的本质是获取界面上的控件值,组装成实体对象后加入集合,并刷新数据源。

第3步:执行新增逻辑

在按钮点击事件中验证输入合法性后,实例化对象并添加到列表中:

private void btnNewConfig_Click(object sender, EventArgs e)
{
    try
    {
        // 假设已获取必要参数
        string _lampNo = UpDownSelfLampNo.Value.ToString();
        int _ctrlGpNo = Convert.ToInt16(UpDownCtrlGpCnt.Value);
        // ... 其他参数获取逻辑 ...
        
        if (CheckNewConfigIsLega(_ctrlGpNo, _opCtuch)) // CheckNewConfigIsLega 为自定义校验函数
        {
            string _opType = rbCgOpen.Checked ? "01" : rbCgClose.Checked ? "00" : "02";
            selfRunConfigs.Add(new SelfRun(_opCtuch, _opType, Convert.ToInt32(UpDownTime.Value)));
        }
        
        // 刷新显示
        BindGridViewForIList<SelfRun>(gcConfigShow, selfRunConfigs);
    }
    catch (Exception ex)
    {
        MessageBox.Show(string.Format("新增配置失败,原因:{0}", ex.Message.Trim()));
    }
}

界面预览如下:

点击保存后的效果如图:

修改现有行数据

修改功能通常需要两个阶段:一是读取当前行数据到编辑控件;二是保存修改后的数据覆盖原记录。

第4步:读取行数据填充界面

首先需要确保DataGridView的属性设置为SelectionMode = FullRowSelect,以便单击整行。在处理CellClick事件时,判断点击的是有效行,然后将各列值映射回对应的UI控件:

private void gcConfigShow_CellClick(object sender, DataGridViewCellEventArgs e)
{
    if (e.RowIndex < 0) return;
    DataGridView _dgv = (DataGridView)sender;
    
    // 填充单选框
    string _opWay = _dgv.Rows[e.RowIndex].Cells["OpWay"].Value.ToString();
    switch (_opWay)
    {
        case "00": ThreadSafeOpRadioButton(rbCgClose, true); break;
        case "01": ThreadSafeOpRadioButton(rbCgOpen, true); break;
        case "02": ThreadSafeOpRadioButton(rbSaveOne, true); break;
    }

    // 填充复选框组 (示例为8个通道)
    string _opCtuch = _dgv.Rows[e.RowIndex].Cells["OpCtuCh"].Value.ToString();
    for (int i = 0; i < _opCtuch.Length; i++)
    {
        if (i == 0) ThreadSafeCheckBox(ckch1, _opCtuch[i] == '1');
        if (i == 1) ThreadSafeCheckBox(ckch2, _opCtuch[i] == '1');
        // ... 依此类推 ckch3-ckch8 ...
        if (i == 7) ThreadSafeCheckBox(ckch8, _opCtuch[i] == '1');
    }

    // 填充数值框
    string _timeStr = _dgv.Rows[e.RowIndex].Cells["OpTime"].Value.ToString();
    if (decimal.TryParse(_timeStr, out decimal timeVal))
    {
        ThreadSfeOpUpDown(UpDownTime, timeVal);
    }
}

配置选择模式截图:

第5步:保存修改

当用户完成编辑并点击“修改配置”按钮时,从IList中找到对应索引的元素并更新属性,然后移除旧项添加新项以触发绑定刷新:

private void btnUpdateConfig_Click(object sender, EventArgs e)
{
    try
    {
        if (CheckSelectedRow())
        {
            int _rowIndex = gcConfigShow.CurrentCell.RowIndex;
            // 重新收集界面数据
            string _opWay = rbConfig.Checked ? "1" : "0";
            string _opCtuch = GetSelectedCtuCh();
            string _opType = rbCgOpen.Checked ? "01" : rbCgClose.Checked ? "00" : "02";

            // 更新实体
            SelfRun updatedItem = selfRunConfigs[_rowIndex];
            updatedItem.OpCtuCh = _opCtuch;
            updatedItem.OpTime = Convert.ToInt32(UpDownTime.Value);
            updatedItem.OpWay = _opType;

            // 替换操作:移除旧引用,添加新对象(确保反射/绑定能识别变化)
            selfRunConfigs.RemoveAt(_rowIndex);
            selfRunConfigs.Add(updatedItem);

            BindGridViewForIList<SelfRun>(gcConfigShow, selfRunConfigs);
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(string.Format("修改配置失败,原因:{0}", ex.Message.Trim()));
    }
}

删除行数据

删除操作相对简单,确认用户意图后从IList中移除对应索引的对象,并再次刷新视图。

第6步:执行删除逻辑

private void btnDeleteConfig_Click(object sender, EventArgs e)
{
    if (CheckSelectedRow())
    {
        DialogResult result = MessageBox.Show("是否确定删除该行数据?", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
        if (result == DialogResult.Yes)
        {
            int rowIndex = gcConfigShow.CurrentCell.RowIndex;
            selfRunConfigs.RemoveAt(rowIndex);
            BindGridViewForIList<SelfRun>(gcConfigShow, selfRunConfigs);
        }
    }
}

总结

通过上述步骤,我们实现了基于BindingList和List混合管理的DataGridView全生命周期操作。关键在于理解:修改时需要通过移除并重添加来强制刷新UI(除非实体本身实现了INotifyPropertyChanged),而删除和增加则直接改变集合内容即可。

以上就是WinForm中DataGridView添加、删除、修改操作具体方法的详细内容,更多关于C# WinForm编程的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。