由于直到几天前这似乎对某些人来说仍然是一个问题,包括我自己,所以我想我会发布我的解决方案,以及从现在开始我在课堂上教给学生的解决方案:
首先,我创建一个DataGridView (DGV) 对象并在设计视图中创建列,记下特定列的对象名称。
现在,当我想从我的数据库(SQL Server,对于此代码)绑定数据时。我更改了列对象并将每一列直接绑定到来自DataTable 的数据。
private void FillAddresses()
{
// erase any old data
if (AddrTable != null)
AddrTable.Clear();
else
AddrTable = new DataTable();
// switch-case for panel types that need an address
switch(PanelType)
{
case "Customer":
case "Customers":
case "Location":
case "Locations":
case "Employee":
case "Employees":
BuildStateColumnChoices();
SqlCommand sqlAddrCmd = new SqlCommand();
sqlAddrCmd.CommandText = "exec SecSchema.sp_GetAddress " + PanelType +
"," + ObjectID.ToString(); // Fill the DataTable with a stored procedure
sqlAddrCmd.Connection = DBConnection;
sqlAddrCmd.CommandType = CommandType.Text;
SqlDataAdapter sqlDA = new SqlDataAdapter(sqlAddrCmd);
try
{
sqlDA.Fill(AddrTable);
dgvAddresses.AutoGenerateColumns = false;
// Actually, you set both the DataSource and DataPropertyName properties to bind the data
dgvAddresses.DataSource = AddrTable;
// Note that the column parameters are using the name of the object from the designer.
// This differs from the column names.
// The DataProperty name is set to the column name returned from the Stored Procedure
dgvAddresses.Columns["colAddrType"].DataPropertyName = "Type";
dgvAddresses.Columns["collAddress"].DataPropertyName = "Address";
dgvAddresses.Columns["colAptNum"].DataPropertyName = "Apt#";
dgvAddresses.Columns["colCity"].DataPropertyName = "city";
dgvAddresses.Columns["colState"].DataPropertyName = "State";
dgvAddresses.Columns["colZIP"].DataPropertyName = "ZIP Code";
}
catch(Exception errUnk)
{
MessageBox.Show("Failed to load address data for panel type " +
PanelType + "..." + errUnk.Message, "Address error",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}
break;
}
}
对于上述代码,DBConnection 是我从中获取此代码的对象的公共属性,该对象存储了SqlConnection 对象。此外,colAddressType 是一个 ComboBox 列。来自绑定 DataTable 的数据只能匹配 ComboBox 中列出的信息。类似地,colState 是一个 ComboBox 列,但该框的默认值是通过查询另一个包含所有州的表来添加的(在此示例中为美国)。
这里的重点是,您可以通过在设计时创建列来绑定要包含在 DGV 中的数据,然后将数据从 DataTable 直接绑定到列。这允许您拥有任何类型的列,而不仅仅是默认绑定机制提供给您的默认 TextColumn。
需要注意的是,在这种情况下,DataTable 是存储过程的结果,在这种情况下不太可能进行编辑。我尝试使用视图以及存储函数;第一个也不允许编辑(至少,不容易......我怀疑我需要在某个地方触发之前插入,但这是一个数据库问题),而第二个不会根据一些动态问题返回表表生成。