.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中。但这个新实例从未被显示,用户操作的始终是最初打开子窗体的那个主窗体实例,因此原主窗体的表格不会有任何数据变化。
解决方案
方法一:通过构造函数传递主窗体实例(直接关联)
这种方法适合简单场景,直接将主窗体实例传递给子窗体,让子窗体操作原实例的控件:
- 修改子窗体构造函数,添加主窗体参数:
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(); } } }
- 修改主窗体打开子窗体的代码,传递自身实例:
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(); } }
方法二:通过属性返回选中数据(解耦设计)
这种方法更符合面向对象的解耦原则,子窗体不直接依赖主窗体,而是通过属性返回选中的数据,由主窗体自行处理:
- 子窗体添加属性存储选中数据:
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(); } } }
- 主窗体获取子窗体返回的数据并添加到表格:
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
相关产品推荐
相关产品推荐

