You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8 WinForm跨窗体DataGridView添加行失效问题求助

.NET 8库存管理系统:子窗体双击行无法将数据添加到主窗体DataGridView

问题场景

基于.NET 8、C#、SQL Server开发库存管理系统,主窗体NewPurchaseInvoiceView的DataGridView(ItemsGridList)用于保存发票内容。双击主窗体中红色标记的IDColumn列单元格时,会弹出子窗体ItemsSelectionModeView,该子窗体的DataGridView展示数据库中所有商品。期望双击子窗体的行时,将该行前两列数据添加到主窗体的ItemsGridList,但操作后主窗体表格始终为空。

现有代码

主窗体(NewPurchaseInvoiceView)代码

using System.Windows.Forms;

public partial class NewPurchaseInvoiceView : Form
{
    public NewPurchaseInvoiceView()
    {
        InitializeComponent();
    }

    private void ItemsGridList_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
    {
        if (e.ColumnIndex == ItemsGridList.Columns["IDColumn"].Index && e.RowIndex >= 0)
        {
            ItemsSelectionModeView itemsSelectionModeView = new ItemsSelectionModeView();
            itemsSelectionModeView.ShowDialog();
        }
    }
}

子窗体(ItemsSelectionModeView)代码

using System.Windows.Forms;

namespace HMLalpha.Views
{
    public partial class ItemsSelectionModeView : Form
    {
        public ItemsSelectionModeView()
        {
            InitializeComponent();
        }

        private void ItemsSelectionModeView_Load(object sender, EventArgs e)
        {
            DataTable dataTable = ItemsController.PROCEDURE_DISPLAYALLITEMS();
            ItemsListGridView.Rows.Clear();

            foreach (DataRow dataRow in dataTable.Rows)
            {
                ItemsListGridView.Rows.Add(dataRow[0], dataRow[1], dataRow[2], dataRow[3], dataRow[7], dataRow[4], dataRow[5], dataRow[6]);
            }
        }

        private void ItemSearchTextBox_TextChanged(object sender, EventArgs e)
        {
            DataTable dataTable = ItemsController.PROCEDURE_SEARCHITEMS(ItemSearchTextBox.Text);
            ItemsListGridView.Rows.Clear();

            foreach (DataRow dataRow in dataTable.Rows)
            {
                ItemsListGridView.Rows.Add(dataRow[1], dataRow[2], dataRow[3], dataRow[7], dataRow[4], dataRow[5], dataRow[6]);
            }
        }

        public void ItemsListGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            NewPurchaseInvoiceView newPurchaseInvoiceView = new NewPurchaseInvoiceView();

            foreach (DataGridViewRow dataGridViewRow in ItemsListGridView.SelectedRows)
            {
                newPurchaseInvoiceView.ItemsGridList.Rows.Add(dataGridViewRow.Cells[1].Value.ToString(), 
                    dataGridViewRow.Cells[2].Value.ToString());
            }
            this.Close();
        }   
    }
}

问题根源

子窗体的ItemsListGridView_CellDoubleClick事件中,新建了一个NewPurchaseInvoiceView的实例newPurchaseInvoiceView,并将数据添加到这个新实例的ItemsGridList中。但这个新实例从未被显示,用户操作的始终是最初打开子窗体的那个主窗体实例,因此原主窗体的表格不会有任何数据变化。

解决方案

方法一:通过构造函数传递主窗体实例(直接关联)

这种方法适合简单场景,直接将主窗体实例传递给子窗体,让子窗体操作原实例的控件:

  1. 修改子窗体构造函数,添加主窗体参数:
using System.Windows.Forms;
// 替换为主窗体所在的命名空间
using YourNamespace; 

namespace HMLalpha.Views
{
    public partial class ItemsSelectionModeView : Form
    {
        private NewPurchaseInvoiceView _mainForm;

        // 修改构造函数,接收主窗体实例
        public ItemsSelectionModeView(NewPurchaseInvoiceView mainForm)
        {
            InitializeComponent();
            _mainForm = mainForm;
        }

        // 保留原有Load、TextChanged事件代码...

        private void ItemsListGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            foreach (DataGridViewRow dataGridViewRow in ItemsListGridView.SelectedRows)
            {
                // 使用传递过来的主窗体实例添加行
                _mainForm.ItemsGridList.Rows.Add(
                    dataGridViewRow.Cells[1].Value.ToString(), 
                    dataGridViewRow.Cells[2].Value.ToString()
                );
            }
            this.Close();
        }   
    }
}
  1. 修改主窗体打开子窗体的代码,传递自身实例:
private void ItemsGridList_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex == ItemsGridList.Columns["IDColumn"].Index && e.RowIndex >= 0)
    {
        // 传递当前主窗体实例给子窗体
        ItemsSelectionModeView itemsSelectionModeView = new ItemsSelectionModeView(this);
        itemsSelectionModeView.ShowDialog();
    }
}

方法二:通过属性返回选中数据(解耦设计)

这种方法更符合面向对象的解耦原则,子窗体不直接依赖主窗体,而是通过属性返回选中的数据,由主窗体自行处理:

  1. 子窗体添加属性存储选中数据:
using System.Collections.Generic;
using System.Windows.Forms;

namespace HMLalpha.Views
{
    public partial class ItemsSelectionModeView : Form
    {
        // 用于存储选中的商品数据
        public List<string[]> SelectedItems { get; private set; } = new List<string[]>();

        public ItemsSelectionModeView()
        {
            InitializeComponent();
        }

        // 保留原有Load、TextChanged事件代码...

        private void ItemsListGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            SelectedItems.Clear();
            foreach (DataGridViewRow dataGridViewRow in ItemsListGridView.SelectedRows)
            {
                // 将选中行的前两列数据存入属性,处理空值避免报错
                SelectedItems.Add(new[] {
                    dataGridViewRow.Cells[1].Value?.ToString() ?? string.Empty,
                    dataGridViewRow.Cells[2].Value?.ToString() ?? string.Empty
                });
            }
            // 设置DialogResult,通知主窗体操作完成
            this.DialogResult = DialogResult.OK;
            this.Close();
        }   
    }
}
  1. 主窗体获取子窗体返回的数据并添加到表格:
private void ItemsGridList_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex == ItemsGridList.Columns["IDColumn"].Index && e.RowIndex >= 0)
    {
        ItemsSelectionModeView itemsSelectionModeView = new ItemsSelectionModeView();
        if (itemsSelectionModeView.ShowDialog() == DialogResult.OK)
        {
            // 遍历子窗体返回的选中数据,添加到主窗体表格
            foreach (var item in itemsSelectionModeView.SelectedItems)
            {
                ItemsGridList.Rows.Add(item[0], item[1]);
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者Ali Aker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 17:31:09