使用动态列填充Datagrid
我有一个需要动态填充的Datagrid。
tablelayout就像:
id | image | name | Description | Name-1 | Name-N
前4列是静态的,其他列是动态的。 用户应该能够根据需要添加尽可能多的用户。
我尝试通过将多个用户的数据放在表中彼此相邻来比较它们的数据。
现在我有一个Listbox whitch包含动态生成的Columns的名称和一个填充静态列的方法。 我也可以为每个用户加载数据。 现在我需要将它们合并到一个大表中。
现在的主要问题是:如何将“Userdata”和静态内容放在一个数据网格中。
至少有三种方法可以做到这一点:
- 从代码隐藏中手动修改DataGrid的列
- 使用DataTable作为ItemsSource *
-
使用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,Description的DataGrid ,并且当在该DataGrid上选择其中一个记录时,您将显示/刷新一个ListBox与所选记录相关的图像名称