我有一个遵循表格的类:
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中显示一个Cats列表,如下所示:
---------------------------------------------------------------------------------
| 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的Cheezbugers.如果你只是尝试绑定Cats列表,你将不会得到这种行为.
问题是我无法弄清楚如何在DataGridView和Cats.Cheezbugers列表中的各个项之间执行复杂的源绑定.值得一提的是,我确信列表中的每只猫在其列表中都有相同数量的Cheezbugers.
编辑:
我知道DataGridView complex binding问同样的问题,但只有当我知道提前列表中有多少项目时,接受的答案才有效,但事实并非如此.我所知道的是,所有列表都具有相同的长度.
解决方法:
这不仅仅是一个“复杂绑定”,这是一个Pivot,您希望将详细重复数据(列表’cheezburgers)转换为单行,并且该行具有未确定的列数.
我相信这里最好的选择是编写一个自定义序列化程序,它允许您将数据转换为xml数据表中的行,然后绑定到该行.由于你的列数不一致,xml会更宽容,但我不确定DataGridView将如何处理它.
编辑后续
由于我不知道DataGridView如何处理XML DataTable,我决定将其编写并测试它.我按照我的预期工作,我相信你会想要的.
>这是你的猫和猫cheezburger类(略有修改)
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; }
};
>然后你需要创建一个简单的表单,其中有两个按钮“bind to object”(button1)和“bind to datatable”(button2),DataGridView固定在底部.并将表单编码为:
//在编辑器中,下一行是在代码块中,一旦我保存它就不是..
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列,名称&描述6列cheezburger信息,排列为(我相信)你想要的.