【问题标题】:How to create LookUp fields in DataGridView?如何在 DataGridView 中创建查找字段?
【发布时间】:2010-07-25 17:23:09
【问题描述】:

在我的DataGridView 中,我正在显示一个表中的大量列。在这个表中,我有一列指向另一个表中的项目。您可能已经猜到了,我想在一列的网格中显示第二个表中的一些文本值,而不是 ItemID。 我在网上找不到正确的示例如何做到这一点。

假设我在数据库中有两个表:

表用户:

UserID UserName UserWorkplaceID
  1     Martin        1
  2     John          1
  3     Susannah      2
  4     Jack          3

工作台:

WorkplaceID WorkplaceName
     1        "Factory"
     2        "Grocery"
     3        "Airport"

我有一个无类型数据集dsUsers、一个绑定源bsUsers和两个用于填充数据集的DataAdaptersdaUsersdaWorkplaces)。

我正在执行的代码:

daUsers.Fill(dsUsers);
daWorkplaces.Fill(dsUsers);
bsUsers.DataSource = dsUsers.Tables[0];
dgvUsers.DataSource = bsUsers;

此时我在dgvUsers 中看到三列,UserID、UserName 和 UserWorkplaceID。但是,不是 UserWorkplaceID 和值 1、2、3,我想看到“工厂”、“杂货店”等等......

所以我在dgvUsers 添加了另一个名为“WorkplaceName”的列,在我的代码中我试图将它绑定到新创建的关系:

dsUsers.Relations.Add("UsersWorkplaces", dsUsers.Tables[1].Columns["WorkplaceID"], dsUsers.Tables[0].Columns["UserWorkplaceID"]);

WorkplaceName.DataPropertyName = "UsersWorkplaces.WorkplaceName";

不幸的是,这不起作用。关系创建没有错误,但运行程序后此列中的字段为空。

我做错了什么?

我还想询问一个在 DataGridView 中使用 LookUp 组合框的示例,它允许我更改 UserWorkplaceID,但它会显示一个位于 WorkplaceName 下的 tex 值,而不是数值。

感谢您的宝贵时间。

【问题讨论】:

    标签: c# datagridview lookupfield


    【解决方案1】:

    在我看来,最好的决定是使用 DataGridViewComboBoxColumn 列类型。如果这样做,您应该预先创建一个带有查找数据的数据适配器,然后设置 DataGridViewComboBoxColumn 的 DataSource、DataPropertyName、DisplayMember 和 ValueMember 属性。您还可以将 DisplayStyle 属性设置为 Nothing 以使该列看起来像一个公共数据列。就是这样。

    【讨论】:

      【解决方案2】:

      我不知道您是否可以完全按照您的意愿行事,这似乎将 DataGridView 同时绑定到两个不同的 DataTable 实例。我不认为DataGridView 类支持这一点——或者如果它支持,那是我没见过的忍者风格的举动。

      Per MSDN,您最好的选择可能是在 DataGridView 上使用 CellFormatting 事件并检查正在格式化的单元格何时在查找列中,然后您可以从另一个表中替换您的值。为 WorkplaceName 列使用未绑定的列,隐藏 UserWorkplaceID 列,然后实现 CellFormatting 事件句柄以查找行中的值,例如:

      private void dgv_CellFormatting(object sender, 
          DataGridViewCellFormattingEventArgs e)
      {
          if (dgv.Columns[e.ColumnIndex].Name.Equals("WorkplaceName")
          {
              // Use helper method to get the string from lookup table
              e.Value = GetWorkplaceNameLookupValue(
                  dataGridViewScanDetails.Rows[e.RowIndex].Cells["UserWorkplaceID"].Value);
          }
      }
      

      如果您有很多行可见,这可能会影响性能,但可能是使其正常工作的一种不错的方式。

      如果这对您没有吸引力,可以使用DataTable.Merge() 方法将您的查找表合并到您的主表中。快速浏览我的一本 ADO.NET 书籍表明这应该可行,尽管我还没有尝试过。但我不确定这是否与您之前提出的想法过于接近。

      至于您关于查找组合框的第二个问题,您真的应该将其发布在一个单独的问题中,以便得到适当的关注。

      【讨论】:

      • 谢谢,我在想 ComboBox 和 TextBox 在它们的行为/属性上是相似的。我错了。
      【解决方案3】:

      您可以改为让 SQL 来完成这项工作。使用连接返回带有 Workplace 名称而不是 ID 的表,将该表输出到数据集中并使用它。

      例如。

      SELECT A.UserID, A.UserName, B.WorkplaceID
         FROM Users A 
         JOIN Workplaces B ON A.UserWorkplaceID = B.WorkplaceID
      

      然后使用它的输出来填充 dsUsers。

      【讨论】:

      • 感谢您的想法,但我不想这样做。我想要的正是我在问题中描述的内容。
      猜你喜欢
      • 2018-02-05
      • 2018-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-13
      • 2022-10-24
      • 1970-01-01
      相关资源
      最近更新 更多