我正在寻找一种方法来显示DataGrid
来自编译时未知类型的数据。
我有以下基础课
public abstract class Entity
{
// Some implementation of methods ...
}
在运行时,我加载了一个插件DLL,并使用反射来获取从派生的所有类型的列表Entity
。例如:
public class A : Entity
{
public LocalAddress Address{ get; set; }
}
public class B : Entity
{
public Vendor Vendor { get; set; }
public string Name { get; set; }
}
然后我从数据库检索他们的实例列表
public IEnumerable<Entity> Entities { get; set; } // A list of instances of type A for example
Entities
是DataGrid的ItemsSource
,但是将属性绑定到的最佳方法是DataGrid
什么?由于属性可能很复杂,因此我还需要能够绑定到特定路径,例如Address.HomeNum
...
我只需要一次显示一个类型实例的网格。完整的方案是这样的:
Entity
通过反射从插件DLL派生的类型的列表A
和B
A
,我A
从DB中获得了一个实例列表-到目前为止,情况很好。A
的实例中DataGrid
。B
)时,我B
从DB获得了的实例列表,需要在网格中显示这些实例,依此类推...插件DLL是一个没有xamls的类库(我的用户也是制作此插件的用户,我不希望他们DataTemplate
为自己的实体写s。我也不能DataTemplate
像我一样制作predifned s我不知道要等到运行时才显示的类型。每种类型可以具有不同的类型和数量的属性Entity
。
由于您事先不知道Entities的属性名称,因此我认为最好的选择是将DataGrid保留在Xaml中,但将其DataGridColumns的定义和绑定移到后面的代码中。
AddColumnsForProperty(PropertyInfo property, string parentPath = "")
{
var title = property.Name;
var path = parentPath + (parentPath=="" ? "" : ".") + property.Name;
if(property.PropertyType == typeof(string))
{
var column = new DataGridTextColumn();
column.Header = title;
column.Binding = new Binding(path);
dataGrid.Columns.Add(column);
}
else if(property.PropertyType == typeof(bool))
{
//use DataGridCheckBoxColumn and so on
}
else
{
//...
}
var properties = property.GetProperties();
foreach(var item in properties)
{
AddColumnsForProperty(item, path);
}
}
现在,如果执行这些操作,则将填充dataGrid列。并通过在可观察的集合中添加所需类型的所有实例,并将其绑定到DataGrid的ItemsSource,它应该可以工作。selectedItem应该是从Entity派生的类之一的实例。列表框包含new A()
和new B()
(或A和B的任何现有实例),因此在以下语句中可以使用selectedItem。
var propertyList = selectedItem.GetType().GetProperties();
foreach (var property in propertyList)
AddColumnsForProperty(PropertyInfo property);
如何在代码中编写DataGridColumnTemplate
编辑:
在这种情况下不能使用成员,因为INotifyPropertyChanged应该参与,所以我用属性替换了成员。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句