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

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

问题描述

我有如下形式的类:

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; }
};



我希望能够以显示列表在这个猫的 DataGridView的如下:

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



等等......我们的目标是,列出所有的 Cheezbuger S也是一样排。如果你只是试图结合就是你不会得到这种行为的清单。

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的列表中的各个项目之间源结合。对于什么样的价值,我知道肯定每个在列表中具有相同数目的 Cheezbuger S IN的其。名单

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.

修改FOLLOWS
因为我没有'知道'在DataGridView将如何处理XML数据表,我决定把它写起来并进行测试。我的作品我没有料到,我相信你会如何想。

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; }
};


  • 然后你需要创建一个简单的形式有两个按钮绑定到对象(按钮1)和绑定到数据表(按钮2),与固定在底部的一个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列,他们将创建动态的基础数据源。绑定到猫的列表将让你两列(名称/描述)绑定到DataTable得到8列,名称和放大器;的cheezburger信息描述+ 6列,一字排开如(我相信)你想要的。

    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天全站免登陆