如何将复杂对象绑定到DataGridView? [英] How does one bind a complex object to a DataGridView?

查看:118
本文介绍了如何将复杂对象绑定到DataGridView?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类可以遵循以下格式:

I have a class that follows the form:

public class Cat
{
    public string Name { get; set; }
    public string Description {get; set; }
    public List<Cheezburger> Cheezbugers { get; private set; }
};

public class Cheezburger
{
    public int PattyCount { get; set; }
    public bool CanHaz { get; set; }
};

我想要显示一个列表 Cats这在一个 DataGridView 如下:

I want to be able to display a List of Cats this in a DataGridView as follows:

---------------------------------------------------------------------------------
| Name     | Description  |  PattyCount | CanHaz   | PattyCount   | CanHaz  | etc
--------------------------------------------------------------------------------
| Felix    | Classic Cat  |  1          | true     | 3            | false   | etc
| Garfield | Fat,Lazy Cat |  2          | false    | 7            | true    | etc

等等...目标是列出所有的 Cat Cheezbuger 在同一行。如果你只是尝试绑定 Cat 的列表,你将不会得到这种行为。

And so on... The goal being to list out all the Cat's Cheezbugers in the same row. If you simply try binding the list of Cats you won't get this behavior.

问题是我不知道如何在 DataGridView Cats.Cheezbugers列表中的各个项目之间做一个复杂的绑定/ code>。对于它的价值,我确定列表中的每个 Cat 的数量与其中的$ code> Cheezbuger 相同列表。

The problem is that I can't figure out how to do a do a complex binding of source between the DataGridView and the individual items in the list of Cats.Cheezbugers. For what its worth, I know for sure that each Cat in the list has the same number of Cheezbugers in its list.

修改

我知道DataGridView复合绑定提出同样的问题,但接受的答案只有在我提前知道列表中有多少项目时才能工作,而不是这样。我所知道的是,所有的列表将具有相同的长度。

I am aware that DataGridView complex binding asks the same question, but the accepted answer works only if I know how many items are in the list ahead of time, and that is not the case. All I know is that all the lists will have the same length.

推荐答案

这不仅仅是一个复杂的绑定是一个

数据透视,您希望将详细重复数据(列表o'cheezburgers)转换为单个行,该列具有不确定的列数。

This isn't just a 'complex binding' this is a Pivot, where you are wanting to transform detail repeating data (the list o' cheezburgers) to a single row, and that row has an undetermined number of columns.

我相信你最好的选择是编写一个自定义的序列化程序,它将允许你将数据转换成xml数据表中的行,然后绑定到它。由于您的列数将不一致xml将更加宽容,尽管我不知道DataGridView将如何处理它。

I believe your best option here is to write a custom serializer that will allow you to transform your data into rows in an xml datatable and then bind to that. Since your column count is going to be inconsistent xml will be more forgiving, though I am not sure how the DataGridView will handle it.

编辑跟踪
由于我不知道DataGridView如何处理XML DataTable,所以我决定写下来并对其进行测试。我的工作原理如何,我相信你会想要什么。

EDIT FOLLOWS Since I did not 'know' how the DataGridView would handle the XML DataTable I decided to write it up and test it. I works how I expected, and I believe how you will want.


  1. 这是你的猫& cheezburger类(略有修改)

  1. Here are your cat & cheezburger classes (slightly modified)

public class Cat
{
    public string Name { get; set; }
    public string Description { get; set; }
    public List<Cheezburger> Cheezbugers { get; private set; }

    public void AddCheezburger(Cheezburger cheezburger)
    {
        if (this.Cheezbugers == null)
            this.Cheezbugers = new List<Cheezburger>();
        this.Cheezbugers.Add(cheezburger); 
    }
};

public class Cheezburger
{
    public int PattyCount { get; set; }
    public bool CanHaz { get; set; }
};


  • 然后,您需要使用两个按钮绑定到对象(button1)和绑定到datatable(button2),将DataGridView锚定到底部。并编写如下形式:

  • Then you need to create simple form with two buttons "bind to object" (button1) and "bind to datatable" (button2), with a DataGridView anchored to the bottom. and code up the form like:

    //在编辑器中,下一行是在代码块中,一旦我保存它不是..

    //in the editor this next line is in the codeblock, once I save it it isn't..

    public partial class Form1 : Form
    {
    
        List<Cat> cats = new List<Cat>();
    
        public Form1()
        {
            InitializeComponent();
    
            cats.Add(new Cat() { Name = "Felix", Description = "Classic Cat" });
            cats.Add(new Cat() { Name = "Garfield", Description = "Fat,Lazy" });
            cats.Add(new Cat() { Name = "Tom", Description = "Wanna-Be-Mouser" });
            cats[0].AddCheezburger(new Cheezburger() { CanHaz = true, PattyCount = 1 });
            cats[0].AddCheezburger(new Cheezburger() { CanHaz = false, PattyCount = 3 });
            cats[1].AddCheezburger(new Cheezburger() { CanHaz = false, PattyCount = 2 });
            cats[1].AddCheezburger(new Cheezburger() { CanHaz = true, PattyCount = 7 });
            cats[1].AddCheezburger(new Cheezburger() { CanHaz = true, PattyCount = 99 });
            cats[2].AddCheezburger(new Cheezburger() { CanHaz = true, PattyCount = 5 });
            cats[2].AddCheezburger(new Cheezburger() { CanHaz = false, PattyCount = 14 });
    
        }
    
        private void button1_Click(object sender, EventArgs e)
        {
            dataGridView1.DataSource = null;
            dataGridView1.DataSource = cats;
        }
    
        private void button2_Click(object sender, EventArgs e)
        {
            dataGridView1.DataSource = null;
            dataGridView1.DataSource = serializeCats(cats);
        }
    
        private DataTable serializeCats(List<Cat> cats)
        {
    
            DataTable returnTable = new DataTable("Cats");
            returnTable.Columns.Add(new DataColumn("Name"));
            returnTable.Columns.Add(new DataColumn("Description"));
            int setID = 1;
            foreach (Cat cat in cats)
            {
                //If the row requires more columns than are present then add additional columns
                int totalColumnsRequired = (cat.Cheezbugers.Count * 2) + 2;
    
                while (returnTable.Columns.Count < totalColumnsRequired)
                {
                    returnTable.Columns.Add(new DataColumn("Can Haz " + setID.ToString()));
                    returnTable.Columns.Add(new DataColumn("Patty Count " + setID.ToString()));
                    setID++;
                }
                returnTable.AcceptChanges();
                DataRow row = returnTable.NewRow();
                row[0] = cat.Name;
                row[1] = cat.Description;
                int cbi = 2; //cheezburger index
                foreach (Cheezburger cheezburger in cat.Cheezbugers)
                {
                    row[cbi] = cheezburger.CanHaz;
                    cbi++;
                    row[cbi] = cheezburger.PattyCount;
                    cbi++;
                }
    
                returnTable.Rows.Add(row);
            }
            return returnTable;
        }
    }
    

    不要尝试预定义DataGridView列,他们将可以根据数据源动态创建。绑定到列表的cats将会得到你的两列(名称/描述)绑定到DataTable得到8列,名称&描述+ 6列cheezburger信息,排列(我相信)你想要的。

    Do not attempt to predefine the DataGridView columns, they will be created dynamically based on the data source. Binding to the list of cats will get you two columns (name/description) Binding to the DataTable gets 8 columns, name & description + 6 columns of cheezburger info, lined up as (I believe) you want.

    这篇关于如何将复杂对象绑定到DataGridView?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆