如何将DataView数据从一个Windows窗体推送至另一个窗体?
解决主从窗体DataGridView选中行数据传递问题
看起来你在主从窗体的数据传递上踩了几个常见的坑,我来帮你梳理问题并给出正确的实现方式:
先分析你现有代码的核心问题
- 实例化新窗体导致数据丢失:在
form1.Publish()里你新建了一个form2实例,这不是用户正在操作的那个主窗体,自然拿不到选中行的数据。 - 未判断选中行状态:按钮点击时直接访问
SelectedRows[0],如果没有选中行会直接抛出索引越界异常。 - 未显示目标窗体:你创建了
form1但没有调用Show()或ShowDialog(),就算绑定了数据也看不到结果。
正确实现步骤
第一步:配置主窗体(form2)的DataGridView
先确保DataGridView是单选模式(符合主从场景的需求),可以在设计器里设置,或者在窗体构造函数/Load事件里添加代码:
public Form2() { InitializeComponent(); // 设置单选整行选择 Viewer.SelectionMode = DataGridViewSelectionMode.FullRowSelect; Viewer.MultiSelect = false; }
第二步:重写主窗体的按钮点击事件
这里我们直接获取选中行的数据,然后传递给目标窗体(form1),避免窗体间不必要的耦合:
private void button1_Click(object sender, EventArgs e) { // 先判断是否有选中行 if (Viewer.SelectedRows.Count == 0) { MessageBox.Show("请先选择一行企业数据!"); return; } // 获取选中行绑定的原始数据(比直接取Cells更可靠) DataRowView selectedRow = (DataRowView)Viewer.SelectedRows[0].DataBoundItem; // 创建form1实例并传递数据 Form1 detailForm = new Form1(); detailForm.LoadEnterpriseDetails(selectedRow); // 显示详情窗体(用ShowDialog()模态显示,或者Show()非模态,根据需求选) detailForm.ShowDialog(); }
第三步:修改详情窗体(form1)的代码
给form1添加一个接收数据的方法,直接将数据赋值给标签(或者用数据绑定,两种方式都可以):
方式1:直接赋值(简单直观,适合少量标签)
public void LoadEnterpriseDetails(DataRowView enterpriseData) { // 直接给标签赋值,确保字段名和数据库一致 Email.Text = enterpriseData["EmailAddress"]?.ToString() ?? "无邮箱"; // 如果还有其他标签,比如企业名称、地址等,同理处理 // BusinessNameLabel.Text = enterpriseData["BusinessName"]?.ToString() ?? "无名称"; // AddressLabel.Text = enterpriseData["Address"]?.ToString() ?? "无地址"; }
方式2:数据绑定(适合后续可能扩展的场景)
public void LoadEnterpriseDetails(DataRowView enterpriseData) { // 先清除旧的绑定,避免重复绑定 Email.DataBindings.Clear(); // 绑定标签的Text属性到数据行的EmailAddress字段 Email.DataBindings.Add("Text", enterpriseData, "EmailAddress"); }
额外优化建议
- 避免SQL注入风险:如果你的
RowFilter用到字符串拼接,记得处理单引号(比如把'替换成''),不过上面用DataRowView的方式不需要筛选,直接用原始数据,更安全高效。 - 空值处理:数据库字段可能为null,建议在赋值时添加空值判断,避免出现空引用异常。
- 窗体复用:如果需要多次打开详情窗体,可以考虑复用同一个实例,而不是每次新建,减少资源消耗。
内容的提问来源于stack exchange,提问作者Esco
相关产品推荐
相关产品推荐

