简体   繁体   English

如何在DataGridView中创建LookUp字段?

[英]How to create LookUp fields in DataGridView?

In my DataGridView I'am displaying a buch of columns from one table. 在我的DataGridView我从一个表中显示了一列列。 In this table I have a column which points to item in another table. 在这个表中,我有一个列指向另一个表中的项目。 As you may already guessed, I want to display in the grid in one column some text value from the second table instead of and ItemID. 正如您可能已经猜到的那样,我想在一列中的网格中显示第二个表中的一些文本值而不是和ItemID。 I could not find a right example on the net how to do this. 我在网上找不到一个正确的例子如何做到这一点。

Lets assume that I have two tables in databes: 让我们假设我在数据库中有两个表:

Table Users: 表用户:

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

Table Workplaces: 表工作场所:

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

I have one untyped dataset dsUsers , one binding source bsUsers , and two DataAdapters for filling dataset ( daUsers , daWorkplaces ). 我有一个无类型数据集dsUsers ,一个绑定源bsUsers和两个DataAdapters用于填充数据集( daUsersdaWorkplaces )。

Code which I am performing: 我正在执行的代码:

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

At this point I see in my dgvUsers three columns, UserID, UserName and UserWorkplaceID. 此时我在dgvUsers看到三列,UserID,UserName和UserWorkplaceID。 However, instead of UserWorkplaceID and values 1,2,3 I would like to see "Factory", "Grocery" and so on... 但是,我希望看到“工厂”,“杂货”等等,而不是UserWorkplaceID和值1,2,3 ...

So I've added another column to dgvUsers called "WorkplaceName" and in my code I am trying to bind it to the newly created relation: 所以我在dgvUsers添加了另一个名为“WorkplaceName”的列,在我的代码中我试图将它绑定到新创建的关系:

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

WorkplaceName.DataPropertyName = "UsersWorkplaces.WorkplaceName";

Unfortunately that doesn't work. 不幸的是,这不起作用。 Relation is created without errors but fields in this column are empty after running the program. 创建关系时没有错误,但运行程序后此列中的字段为空。

What I am doing wrong? 我做错了什么?

I would like to also ask about an example with LookUp combobox in DataGridView which allow me to change the UserWorkplaceID but instead of numeric value it will show a tex value which is under WorkplaceName. 我还想问一下DataGridView中使用LookUp组合框的示例,它允许我更改UserWorkplaceID,但是它将显示一个在WorkplaceName下的tex值而不是数值。

Thanks for your time. 谢谢你的时间。

In my opinion, the best decision would be to use the DataGridViewComboBoxColumn column type. 在我看来,最好的决定是使用DataGridViewComboBoxColumn列类型。 If you do it, you should create a data adapter with lookup data beforehand and then set DataSource, DataPropertyName, DisplayMember, and ValueMember properties of the DataGridViewComboBoxColumn. 如果这样做,您应该事先创建一个包含查找数据的数据适配器,然后设置DataGridViewComboBoxColumn的DataSource,DataPropertyName,DisplayMember和ValueMember属性。 You could also set the DisplayStyle property to Nothing to make the column look like a common data column. 您还可以将DisplayStyle属性设置为Nothing,以使列看起来像公共数据列。 That's it. 而已。

I don't know if you can do exactly what you want, which seems to be binding the DataGridView to two different DataTable instances simulataneously. 我不知道你是否可以做你想要的,这似乎是将DataGridView同时绑定到两个不同的DataTable实例。 I don't think the DataGridView class supports that -- or if it does it's a ninja-style move I haven't seen. 我不认为DataGridView类支持 - 或者如果它这样做是一个忍者风格的举动,我没有看到。

Per MSDN , your best bet is probably using the CellFormatting event on the DataGridView and check for when the cell being formatted is in the lookup column, then you could substitute your value from the other table. 根据MSDN ,您最好的选择可能是使用DataGridView上的CellFormatting事件并检查格式化的单元格何时位于查找列中,然后您可以替换其他表中的值。 Use an unbound column for the WorkplaceName column, hide the UserWorkplaceID column and then implement the CellFormatting event handle to look up the value in the row, eg: 对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);
    }
}

If you've got a lot of rows visible, this might impact performance but is probably a decent way to get it working. 如果你看到很多行,这可能会影响性能,但可能是让它运行起来的一种不错的方法。

If this doesn't appeal to you, maybe use the DataTable.Merge() method to merge your lookup table into your main table. 如果这对您没有吸引力,可以使用DataTable.Merge()方法将查找表合并到主表中。 A quick glance at one of my ADO.NET books suggests this should work, although I have not tried it. 快速浏览一下我的ADO.NET书籍表明这应该有效,尽管我还没有尝试过。 But I'm not sure if this is too close to the idea suggested previously which you shot down. 但是我不确定这是否与之前提出的你击落的想法太接近了。

As for your second question about the lookup combobox, you should really post it in a separate question so it gets proper attention. 至于你关于查找组合框的第二个问题,你应该把它发布在一个单独的问题中,以便得到适当的关注。

You could make SQL do the job instead. 您可以让SQL完成工作。 Use a join to return a table with Workplace names instead of IDs, output that table into a dataset and use it instead. 使用连接返回具有Workplace名称而不是ID的表,将该表输出到数据集中并使用它。

eg. 例如。

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

Then use its output to fill dsUsers. 然后使用其输出来填充dsUsers。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM