双击DataGridView行将数据加载至另一窗体文本框的实现疑问
解决WinForms窗体间数据传递的实现方案
嘿,刚接触编程和Stack Overflow的话别担心,这个需求其实挺常见的,咱们一步步来搞定它:
1. 先给SearchForm的DataGridView加触发事件
首先打开SearchForm的设计界面,找到你的DataGridView控件——要么直接双击它(会自动生成双击事件),要么在属性面板的「事件」里找CellDoubleClick绑定方法。如果你想实现“选中行就触发”,那可以绑定SelectionChanged事件,不过双击操作对用户来说更明确,咱们先以双击为例:
private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e) { // 先判断是不是点到了有效行(别点表头哦) if (e.RowIndex >= 0) { // 获取选中的那一行 DataGridViewRow selectedRow = dataGridView1.Rows[e.RowIndex]; // 把数据传给Form1 SendDataToForm1(selectedRow); // 隐藏当前的SearchForm this.Hide(); } }
如果要做选中行就触发,代码类似,把事件换成SelectionChanged就行:
private void dataGridView1_SelectionChanged(object sender, EventArgs e) { if (dataGridView1.SelectedRows.Count > 0) { DataGridViewRow selectedRow = dataGridView1.SelectedRows[0]; SendDataToForm1(selectedRow); // 要是选中就隐藏的话,这里加 this.Hide(); 就行 } }
2. 实现两个窗体间的数据传递
这里有两种常用方法,推荐用事件委托(代码更灵活,耦合度低),简单场景也可以直接传Form1实例:
方法一:事件委托(推荐)
这个方法相当于让SearchForm“通知”Form1:我选中了一行数据,你来接收!
首先在SearchForm类里定义事件和委托:
// 定义一个委托,用来传递选中的行数据 public delegate void RowSelectedHandler(DataGridViewRow selectedRow); // 定义事件,Form1可以订阅这个事件 public event RowSelectedHandler RowSelected; // 触发事件的方法 private void SendDataToForm1(DataGridViewRow selectedRow) { // 检查有没有订阅这个事件的对象(也就是Form1) RowSelected?.Invoke(selectedRow); }
然后回到Form1,打开SearchForm的时候订阅这个事件:
// 比如Form1里有个按钮用来打开SearchForm private void btnOpenSearch_Click(object sender, EventArgs e) { SearchForm searchForm = new SearchForm(); // 订阅SearchForm的RowSelected事件 searchForm.RowSelected += OnSearchRowSelected; searchForm.Show(); // 要是需要模态窗口(必须关了搜索窗才能操作Form1)就用ShowDialog() } // 接收数据并填充Form1的文本框 private void OnSearchRowSelected(DataGridViewRow selectedRow) { // 假设你的Form1里有txtDescription(描述)、txtPrice(价格)、txtEAN(EAN码)三个文本框 // 注意替换成你实际的列名,也可以用索引比如Cells[0],但列名更直观 txtDescription.Text = selectedRow.Cells["描述列名"].Value?.ToString() ?? string.Empty; txtPrice.Text = selectedRow.Cells["价格列名"].Value?.ToString() ?? string.Empty; txtEAN.Text = selectedRow.Cells["EAN码列名"].Value?.ToString() ?? string.Empty; // 这里的?.和??是为了防止单元格为空时报错,空值就显示空字符串 }
方法二:直接传递Form1实例(快速实现)
如果你的项目很小,想快一点搞定,可以直接把Form1的实例传给SearchForm,这样SearchForm能直接操作Form1的控件:
首先在SearchForm里加一个属性:
// 用来存Form1的实例 public Form1 MainForm { get; set; }
然后在Form1打开SearchForm的时候赋值:
private void btnOpenSearch_Click(object sender, EventArgs e) { SearchForm searchForm = new SearchForm(); searchForm.MainForm = this; // 把当前Form1实例传过去 searchForm.Show(); }
接下来在SearchForm的双击事件里直接给Form1的文本框赋值:
private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e) { if (e.RowIndex >= 0) { DataGridViewRow selectedRow = dataGridView1.Rows[e.RowIndex]; // 直接访问Form1的控件,记得要把Form1里的文本框Modifiers属性改成Public/Internal MainForm.txtDescription.Text = selectedRow.Cells["描述列名"].Value?.ToString() ?? string.Empty; MainForm.txtPrice.Text = selectedRow.Cells["价格列名"].Value?.ToString() ?? string.Empty; MainForm.txtEAN.Text = selectedRow.Cells["EAN码列名"].Value?.ToString() ?? string.Empty; this.Hide(); } }
⚠️ 注意:这种方法需要把Form1里的文本框的Modifiers属性改成Public或者Internal,不然SearchForm访问不到。不过耦合度比较高,大型项目不建议用哦。
3. 几个小提醒
- 一定要确保你用的列名和DataGridView里的列名完全一致,不然会找不到单元格报错;
- 处理空值!如果单元格可能为空,一定要用
?.ToString() ?? string.Empty这种写法,避免空引用异常; - 要是用
ShowDialog()打开SearchForm,关闭后会自动回到Form1;用Show()的话,隐藏SearchForm后它还在内存里,后续可以再次显示。
内容的提问来源于stack exchange,提问作者Mustafa
相关产品推荐
相关产品推荐

