C# WinForm打开Form2时字符串转换及DataGridView绑定报错排查
报错原因
两个报错分别由代码里的两类逻辑错误导致:
- "converting string to form"错误:
Form2只定义了需要传入MainForm类型参数的构造函数,但主窗体打开Form2时调用的是无参构造new Form2(),构造函数签名不匹配,触发类型转换异常。 - DataGridView行添加错误:当DataGridView设置了
DataSource进入数据绑定模式后,所有行增删操作必须针对绑定的数据源执行,不能直接调用dataGridView.Rows.Add()方法直接操作行集合;同时原代码还存在跨窗体直接操作控件、文本框取值未取Text属性的额外问题。
修复步骤
1. 修复主窗体打开Form2的构造函数传参错误
修改主窗体按钮点击事件代码,打开Form2时传入当前主窗体实例,匹配Form2的带参构造:
private void button1_Click(object sender, EventArgs e) { // 传入当前主窗体实例this作为构造参数 Form2 frm2 = new Form2(this); frm2.Show(); }
2. 调整主窗体DataGridView绑定逻辑
为了避免跨窗体直接操作控件,在主窗体内声明公开的DataTable作为游戏列表的数据源,在主窗体加载时完成DataGridView绑定:
// 主窗体类内添加公开属性,供Form2访问写入数据 public DataTable GameTable { get; set; } private void MainForm_Load(object sender, EventArgs e) { // 初始化数据表、配置列 GameTable = new DataTable(); GameTable.Columns.Add("Game", typeof(string)); GameTable.Columns.Add("Path", typeof(string)); // 绑定到主窗体DataGridView dataGridView1.DataSource = GameTable; // 配置列显示规则 dataGridView1.Columns["Path"].Visible = false; dataGridView1.Columns["Game"].Width = 138; dataGridView1.ScrollBars = ScrollBars.None; }
3. 修复Form2添加游戏的逻辑
删除直接操作DataGridView行集合的代码,改为向主窗体的绑定数据源写入数据,同时修正文本框取值逻辑(必须取.Text属性,不能直接传入控件对象):
private void button2_Click(object sender, EventArgs e) { // 基础输入校验 if (string.IsNullOrWhiteSpace(txtTitle.Text) || string.IsNullOrWhiteSpace(txtPath.Text)) { MessageBox.Show("请填写游戏名称并选择exe路径"); return; } // 从主窗体的绑定数据源新建行 DataRow drToAdd = mainForm.GameTable.NewRow(); // 给行赋值,注意取文本框的Text属性 drToAdd["Game"] = txtTitle.Text; drToAdd["Path"] = txtPath.Text; // 向数据表添加行,DataGridView会自动同步显示,不需要手动操作Rows集合 mainForm.GameTable.Rows.Add(drToAdd); mainForm.GameTable.AcceptChanges(); // 添加完成后关闭当前添加窗口 this.Close(); }
注意事项
- 所有设置了
DataSource的DataGridView,增删改行必须操作其绑定的数据源(DataTable、BindingList等),直接调用Rows.Add()/Rows.Remove()必然触发绑定错误。 - 跨窗体交互尽量通过公开属性/方法传递数据,不要直接跨窗体修改另一个窗体的控件属性,避免耦合过高引发的异常。
- 文本框、标签这类输入/显示控件,取值时必须访问
.Text属性,直接传入控件对象会得到控件类型的默认字符串(如System.Windows.Forms.TextBox)而非输入内容。
内容的提问来源于stack exchange,提问作者Lachie
相关产品推荐
相关产品推荐

