我创建了一个非常简单的测试,将此问题归结为常见元素。我有一个MS Access DB,其中只有1个表。 2列(ID,Name)并向表中添加了4行数据。以下是重现问题的步骤:
DataSet
的{{1}}。 (从数据库添加新数据源)DataTable
,其中包含1个且仅有1个控件Form1
DataGridView
DataSource
属性)。我的DataGridView
看起来像这样:
Form_Load
当我跳过最后一行代码时,dt为null。我错过了什么?
我知道这很简单,可能很明显,但我没有看到。如果我只是将代码运行回表单,则private void Form1_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'testDBDataSet.TestTable' table. You can move, or remove it, as needed.
this.testTableTableAdapter.Fill(this.testDBDataSet.TestTable);
BindingSource bs = (BindingSource)dgvTestData.DataSource;
DataTable dt = (dgvTestData.DataSource) as DataTable;
}
中包含数据。
我做错了什么?如何使用上述步骤从DataGridView
DataTable
获取BindingSource
的基础DataSource
?
答案 0 :(得分:1)
我做错了什么?
当dgvTestData.DataSource
为BindingSource
时,您不能指望dgvTestData.DataSource as DataTable
返回除null之外的任何内容。
as
运算符就像一个强制转换操作。但是,如果转换不可能,则返回null而不是引发异常。
如何从BindingSource获取基础DataTable?
似乎您将网格绑定到绑定源,其DataSource
设置为DataSet
,其DataMember
是DataTable
的名称。当您使用设计器将网格数据源设置为表格或从数据源窗口拖放Table
并放在表单上时,它是默认行为。因此,如果您遵循默认方案,则可以使用此类代码获取DataTable
:
BindingSource bs = (BindingSource)dgvTestData.DataSource;
var dt = (bs.DataSource as DataSet).Tables[bs.DataMember];
如果您使用的是与默认方案不同的任何其他方案,则只需使用绑定源的DataSource
和DataMember
属性即可提取用于数据的DataTable
- 结合。
有更好的方法吗?
这取决于,为什么不简单地使用:
var dt = this.testDBDataSet.TestTable;