从DataTable指定单元格取值输出到TextBox出现CS002错误咨询
错误原因
你遇到的报错是命名冲突导致的类型不匹配:
- 你窗体上的DataGridView控件命名为
dt mainForm_Load方法内部声明了局部的DataTable dt变量,仅在Load方法内部有效- 在
dt_SelectionChanged事件中访问的dt是DataGridView控件对象,不是存储数据的DataTable,所以直接用dt.Rows[][]索引会触发「无法将[]索引应用于类型为'DataGridViewRow'的表达式」的报错。
修复方案
方法1:声明窗体级DataTable变量(推荐)
- 在Form类的内部、所有方法外部声明全局DataTable:
// 写在你的Form类中,和各个事件方法平级 private DataTable _sourceDt;
- 修改
mainForm_Load代码,把局部DataTable的声明替换为给全局变量赋值:
把原代码中的
DataTable dt = new DataTable();
改为
_sourceDt = new DataTable();
Load方法里后续所有用到这个DataTable的地方,都把dt.替换为_sourceDt.即可。
3. 修改dt_SelectionChanged事件代码,直接从全局DataTable取值:
private void dt_SelectionChanged(object sender, EventArgs e) { // 避免未选中单元格时报空错误 if (dt.CurrentCell == null) return; int rowIndex = dt.CurrentCell.RowIndex; // 按列索引取值,0对应第一列 textBox1.Text = Convert.ToString(_sourceDt.Rows[rowIndex][0]); // 按列名取值,替换为你实际的Excel列名即可 textBox2.Text = Convert.ToString(_sourceDt.Rows[rowIndex]["你的Excel列名"]); }
方法2:直接从DataGridView数据源取值(无需额外声明变量)
不需要修改现有Load方法的代码,直接修改SelectionChanged事件即可:
private void dt_SelectionChanged(object sender, EventArgs e) { if (dt.CurrentCell == null) return; int rowIndex = dt.CurrentCell.RowIndex; // 直接把DataGridView的数据源转成DataTable使用 DataTable sourceDt = dt.DataSource as DataTable; if (sourceDt == null) return; textBox1.Text = Convert.ToString(sourceDt.Rows[rowIndex][0]); textBox2.Text = Convert.ToString(sourceDt.Rows[rowIndex]["你的Excel列名"]); }
额外优化建议
- 建议给控件和变量起语义化的名称,比如DataGridView命名为
dgvInventory,DataTable命名为dtInventory,避免重名冲突同时提升代码可读性 - 取值前建议加空值判断,避免单元格为空时抛出格式转换异常
- 如果列名是从Excel读取的,注意列名的大小写、空格要完全匹配,否则会触发找不到列的报错
内容的提问来源于stack exchange,提问作者Joe Fisher
相关产品推荐
相关产品推荐

