c# – WPF:在MVVM中创建绑定到未知类型的最佳方法

我正在寻找一种方法来显示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; }
}

然后我从DB中检索他们的实例列表

public IEnumerable<Entity> Entities { get; set; } // A list of instances of type A for example

实体是DataGrid的ItemsSource,但是我可以将属性绑定到DataGrid的最佳方法是什么?
由于属性可能很复杂,我还需要能够绑定到特定路径,例如Address.HomeNum …

澄清

>我只需要一次显示一个类型实例的一个网格.完整的场景是这样的:

>我从插件DLL中通过反射得到了一个从Entity派生的类型列表
>我在列表中显示他们的名字. (在此示例中,该列表将包含A和B.
>当用户点击特定项目时,让我们说A,我从DB获得A实例列表 – 到目前为止一切顺利.
>我想在DataGrid中显示A的实例列表.
>当用户从列表中选择另一个项目(意思是另一种类型,比方说B)时,我从DB获取B的实例列表,并且需要在网格中显示那些…等等……

>插件DLL是一个没有xamls的类库(我的用户也是制作这个插件的用户,我不希望他们必须为他们的实体编写DataTemplates.
我也不能制作预先设定的DataTemplates,因为我不知道在运行时我需要显示的类型.每种类型都可以具有不同类型和数量的属性.在complie-time中我所知道的只是它们都来自实体.
>网格也应该是可编辑的.

最佳答案
由于您事先不知道实体的属性名称,我认为您最好的选择是将DataGrid保留在Xaml中,但将其DataGridColumns的定义和Bindings移动到后面的代码中.

AddColumnsForMember(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 = member.GetProperties();
     foreach(var item in properties)
     {
          AddColumnsForMember(item, path);
     }
}

现在,如果执行这些操作,您将填充dataGrid列.并通过在可观察集合中添加所需类型的所有实例并将其绑定到DataGrid的ItemsSource,它应该工作. selectedItem应该是从Entity派生的类的一个实例.列表框包含新的A()和新的B()(或A和B的任何现有实例),因此selectedItem可以在以下语句中使用.

var propertyList = selectedItem.GetType().GetProperties();
foreach (var property in propertyList) 
    AddColumnsForMember(PropertyInfo property);

how to write DataGridColumnTemplate in code

编辑:

成员不能在这种情况下使用,因为INotifyPropertyChanged应该参与,所以我用属性替换了成员.

转载注明原文:c# – WPF:在MVVM中创建绑定到未知类型的最佳方法 - 代码日志