【问题标题】:How to bind a collection of objects to a DataGridView in Winforms如何将对象集合绑定到 Winforms 中的 DataGridView
【发布时间】:2014-10-23 15:18:35
【问题描述】:

如果我有两个对象,即Fruit' andColor`,它们的定义如下:

public class Fruit  
{  
  public int FruitId { get; set; }  
  public string Name { get; set; }  
  public Color Color { get; set; }  
}  

public class Color  
{  
  public int ColorId { get; set; }  
  public string Name { get; set; }  
}  

如何将Fruit (e.g. List<Fruit>) 的集合绑定到DataGridView?结果输出类似于以下内容:

+-----+--------+----------+  
| Id  | Name   | Color    |  
+-----+--------+----------+  
| 10  | Apple  | Red      |  
| 20  | Orange | Orange   |  
| 30  | Grapes | Violet   |  
+-----+--------+----------+  

而不像下面的输出:(注意:N.Color 中的 N 表示对象 Color 的命名空间)

+-----+--------+------------+  
| Id  | Name   | Color      |  
+-----+--------+------------+  
| 10  | Apple  | N.Color    |  
| 20  | Orange | N.Color    |  
| 30  | Grapes | N.Color    |  
+-----+--------+------------+  

更新 #1:
我在 SO 上找到了类似的帖子 here 并尝试了关于该帖子的一些建议,但它不起作用......

【问题讨论】:

  • 你的类Color中是否有Color类型属性Color,因为那样你会得到输出N.Color,还有为什么你的颜色类中的Name是类型int ?
  • 哦,我的错,我忘了把它改成字符串。我会尽快修改。
  • 是的,我的 Fruit 类中有一个 Color 类型的属性

标签: c# winforms mvp architectural-patterns


【解决方案1】:

您有多种选择。

您可以在您的Color 类中覆盖ToString 方法以返回Name,例如:

public class Color
{
    public int ColorId { get; set; }
    public string Name { get; set; }
    public override string ToString()
    {
        return Name;
    }
}  

或者,您可以选择匿名对象列表并在结果中选择 NameColor,而不是将 List<Fruit> 分配为 DataSource

var result = yourListOfFruit
                .Select(r => new
                        {
                            FruitID = r.FruitId, 
                            Name = r.Name, 
                            Color = r.Color.Name,
                        }).ToList();

dataGridView1.DataSource = result;

【讨论】:

  • 我正在尝试在基于 MVP 的应用程序中实现上述问题中的概念。如果我覆盖了 Color 的 ToString 方法,那么这是否意味着如果发生这种情况我不能使用它的其他属性拥有除 ColorId 和 Name 之外的其他属性?...
  • @devpro101,我错过了 MVP 标签,我不确定它是如何工作的。此外,覆盖ToString 只会影响您将执行objOfColorType.ToString() 的地方,您仍然可以访问该对象的所有属性。
  • 只是一个简单的问题,如果我使用 datagridview 上的匿名对象来实现您的第二个示例,它是否仍然能够在 Fruit 的属性更改时侦听更新?
  • 我不确定你所说的“听”是什么意思你有一个可观察的集合吗?
【解决方案2】:

好的,在弄清楚如何使我的应用程序运行几天后,我设法找到了一些对解决我的问题有很大帮助的文章。我想我会在这里为你们分享它,所以让我们开始吧:

首先,假设我们已经在变量 fruits 中存储了一个水果列表,并假设我们已经从一个方法中获得了它的值:

List<Fruit> fruits = method();  

现在,我的问题是……如果我使用以下命令将该列表绑定到 datagridview:

datagridview.DataSource = fruits;  

它会给我一个类似于以下的结果:

+-----+--------+------------+  
| Id  | Name   | Color      |  
+-----+--------+------------+  
| 10  | Apple  | N.Color    |  
| 20  | Orange | N.Color    |  
| 30  | Grapes | N.Color    |  
+-----+--------+------------+   

这不是我想要的。所以我想也许如果我以某种方式手动将每一列放到 datagridview 中,我可以指定我的水果列表中要显示的属性。所以我做了这样的事情:

DataGridViewColumn col3 = new DataGridViewTextBoxColumn();  
col3.DataPropertyName = "Color.Name";  
col3.HeaderText = "Color Name";  
dataGridView1.Columns.Add(col3);  

但是,在 DataGridView 列的 DataPropertyName 上指定类似 Color.Name 的内容不起作用,只会导致在 DataGridView 上显示没有数据的空白列。为了让它工作,DataGridView 应该有一个单元格格式化函数,以便在给定的列中正确显示它的值。有关如何进行格式化的完整教程,您可以查看 Antonio Bello 的 博客中的 here

就是这样,希望对你也有帮助^_^

【讨论】:

  • 我建议this
  • 只需使用 Fruit 对象委托创建一个 DisplayFruit 对象并实现 DisplayFruit 属性,但您希望它显示。几乎是下面给出的答案,但没有匿名。如果需要,还允许您修改底层 Fruit 对象的属性。
【解决方案3】:

您可以查看此属性DataGridView.DataSource Property

        // Automatically generate the DataGridView columns.
        dataGridView1.AutoGenerateColumns = true;

        // Set up the data source.
        bindingSource1.DataSource = GetData("Select * From Products");

【讨论】:

  • 我已经完成了那种过程(不完全是,但它很相似)......我现在要做的是生成一个对象的集合,比如 List 然后使用它以某种方式用于 datagridview...
猜你喜欢
  • 2012-02-17
  • 1970-01-01
  • 2013-08-10
  • 1970-01-01
  • 2011-09-15
  • 2010-10-26
  • 1970-01-01
  • 2017-03-22
  • 2012-03-27
相关资源
最近更新 更多