使用winForms + DataGridView绑定到List<T>

34

我正在尝试将一个List<T>绑定到DataGridView控件,但是我没有成功创建自定义绑定。

我尝试过:

gvProgramCode.DataBindings.Add(new Binding("Opcode",code,"Opcode"));

它抛出了一个异常,说找不到该属性名称对应的任何内容。

问题列的名称是“Opcode”。List<T>中的属性名称是Opcode。

ANSWER EDIT: 问题在于我的类中没有将可绑定字段设置为属性,而仅仅是公共字段... 显然这只反映在属性上,而不是字段上。


哈哈,那正是我在评论中添加的内容,很高兴你解决了问题。 - Quintin Robinson
2
+1 我刚遇到了同样的问题。这真是太糟糕了! - Christian Payne
你真是个救星。我已经连续六个小时苦苦思索这个问题,尝试了所有我能想到的、以及所有我能谷歌到的方法,但都没有运气。最后终于找到了你的帖子,当然,我很着急,把它们设成了字段而不是属性。 - Michael
4个回答

14

你绑定到的网格属性也是Opcode吗?如果要直接绑定到List,只需DataSource=list。数据绑定允许自定义绑定。你是否试图做一些不同于数据源的事情?

你得到了一堆空行吗?自动生成的列是否有名称?你是否确认对象中有数据(而不仅仅是空字符串)?

    class MyObject
    {
        public string Something { get; set; }
        public string Text { get; set; }
        public string Other { get; set; }
    }

    public Form1()
    {
        InitializeComponent();

        List<MyObject> myList = new List<MyObject>();

        for (int i = 0; i < 200; i++)
        {
            string num = i.ToString();
            myList.Add(new MyObject { Something = "Something " + num , Text = "Some Row " + num , Other = "Other " + num  });
        }

        dataGridView1.DataSource = myList;
    }

这应该可以正常工作...


是的。如果我只是写 DataSource = list,那么我会得到一堆空列。 - FlySwat
1
所以你只是想将网格绑定到自定义对象列表中的操作码属性? - Quintin Robinson
如果我所问的是转换类型,那么就执行... Grid.DataSource = MyList.Select(o => o.Opcode); - Quintin Robinson
这个类中有三个字符串,Opcode是其中之一。这个类是List<T>的类型,我想让每个字符串成为一列,每个列表项成为一行... - FlySwat
另外一件事是,对象中的字符串是属性而不仅仅是公共字段,对吗?如果您可以发布对象的定义,那可能会有所帮助。 - Quintin Robinson

5

我不太清楚你在尝试做什么,但如果你只是想列出对象,那么绑定到一个通用对象列表相当简单:

    private BindingSource _gridSource;

    private BindingSource GridSource
    {
        get
        {
            if (_gridSource == null)
                _gridSource = new BindingSource();
            return _gridSource;
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        List<FluffyBunny> list = new List<FluffyBunny>();
        list.Add(new FluffyBunny { Color = "White", EarType = "Long", Name = "Stan" });
        list.Add(new FluffyBunny { Color = "Brown", EarType = "Medium", Name = "Mike" });
        list.Add(new FluffyBunny { Color = "Mottled", EarType = "Short", Name = "Torvald" });

        GridSource.DataSource = list;
        dataGridView1.Columns["EarType"].Visible = false; //Optionally hide a column
        dataGridView1.DataSource = GridSource;

    }

如果您只想显示列表类型的特定属性,您应该能够使不需要的列变得不可见。
技术上讲,您并不真正需要创建BindingSource,但我发现如果我需要更新或更改时,这样做会更加容易。
希望这可以帮助您。

当直接绑定到List<T>时,我得到了一堆空行,没有数据。List<T>中的类只包含3个字符串。 - FlySwat
谢谢Jared!你关于BindingSource的评论在我尝试使用List<T>创建新行时帮了我很大的忙。给你点个赞! - Iain Holder

4

我之前也遇到了同样的问题... 我有一个带有公共字段的结构体,但是在网格中没有任何内容。提供公共的getter方法后,问题就得到了解决。


4

我找到的另一个解决方案是使用BindingList集合。



private void Form1_Load(object sender, EventArgs e)
{
   BindingList people= new BindingList {
    new Person {Name="John",Age=23},
    new Person {Name="Lucy",Age=16}
  };

   dataGridView1.DataSource= people;
}

对我来说它很好用,


使用 BindingList<T> 让我在绑定 DataGridView 时受益匪浅!谢谢。 - Patrick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接