使用动态列填充Datagrid

我有一个需要动态填充的Datagrid。

tablelayout就像:

id | image | name | Description | Name-1 | Name-N 

前4列是静态的,其他列是动态的。 用户应该能够根据需要添加尽可能多的用户。

我尝试通过将多个用户的数据放在表中彼此相邻来比较它们的数据。

现在我有一个Listbox whitch包含动态生成的Columns的名称和一个填充静态列的方法。 我也可以为每个用户加载数据。 现在我需要将它们合并到一个大表中。

现在的主要问题是:如何将“Userdata”和静态内容放在一个数据网格中。

至少有三种方法可以做到这一点:

  1. 从代码隐藏中手动修改DataGrid的列
  2. 使用DataTable作为ItemsSource *
  3. 使用CustomTypeDescriptor

    *建议简单


第一种方法:使用代码隐藏在运行时生成DataGrid的列。 这很容易实现,但可能会感觉有点hackish,特别是如果你使用的是MVVM。 所以你有你的DataGrid固定列:

       

准备好“名称”后,通过添加/删除列来修改网格,例如:

 // add new columns to the data grid void AddColumns(string[] newColumnNames) { foreach (string name in newColumnNames) { grid.Columns.Add(new DataGridTextColumn { // bind to a dictionary property Binding = new Binding("Custom[" + name + "]"), Header = name }); } } 

您需要创建一个包装类,它应该包含原始类,以及一个包含自定义属性的字典。 假设你的主行类是“User”,那么你需要一个这样的包装类:

 public class CustomUser : User { public Dictionary Custom { get; set; } public CustomUser() : base() { Custom = new Dictionary(); } } 

使用这个新的“CustomUser”类的集合填充ItemsSource

 void PopulateRows(User[] users, Dictionary[] customProps) { var customUsers = users.Select((user, index) => new CustomUser { Custom = customProps[index]; }); grid.ItemsSource = customUsers; } 

所以把它绑在一起,例如:

 var newColumnNames = new string[] { "Name1", "Name2" }; var users = new User[] { new User { id="First User" } }; var newProps = new Dictionary[] { new Dictionary { "Name1", "First Name of First User", "Name2", "Second Name of First User", }, }; AddColumns(newColumnNames); PopulateRows(users, newProps); 

第二种方法:使用DataTable 。 这使用了引擎盖下的自定义类型基础结构,但更易于使用。 只需将DataGrid的ItemsSource绑定到DataTable.DefaultView属性:

  

然后您可以根据需要定义列,例如:

 Data = new DataTable(); // create "fixed" columns Data.Columns.Add("id"); Data.Columns.Add("image"); // create custom columns Data.Columns.Add("Name1"); Data.Columns.Add("Name2"); // add one row as an object array Data.Rows.Add(new object[] { 123, "image.png", "Foo", "Bar" }); 

第三种方法:利用.Net类型系统的可扩展性。 具体来说,使用CustomTypeDescriptor 。 这允许您在运行时创建自定义类型; 这反过来使您能够告诉DataGrid您的类型具有属性“Name1”,“Name2”,…“NameN”,或者您想要的任何其他属性。 请参阅此处以获取此方法的简单示例。

第二种方法 :使用DataTable。 这使用了引擎盖下的自定义类型基础结构,但更易于使用。 只需将DataGrid的ItemsSource绑定到DataTable.DefaultView属性:

这几乎工作,但我没有绑定到DataTable.DefaultView属性属性,而是创建了一个DataView类型的属性并绑定到该属性。

  

如果您不需要将其显示到一个大的DataGrid(表)中,那么您可以拥有一个带有id,image,name,DescriptionDataGrid 并且当在该DataGrid上选择其中一个记录时,您将显示/刷新一个ListBox与所选记录相关的图像名称