c# – 使用MVVM中的一个视图对多种类型的CRUD进行操作

我有三种类型的项目如下:

public class StockItem
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal UnitPrice { get; set; }
}

public class LotItem : StockItem
{
    public virtual ICollection<Lot> Lots { get; set; }
}
public class DetailedItem : StockItem
{
    public virtual ICollection<SerialNumber> SerialNumbers { get; set; }
}

当我开发一个使用MVVM,WPF,PRISM,EF5的应用程序时,我有点困惑:

第一:我如何使用一个根据类型更改(显示/隐藏控件)的视图对这些类型执行CRUD,知道我可能在以后继承相同类型的新类型?
第二:我如何将视图绑定到视图模型:

>我是否需要公开动态属性才能处理这三种类型?
> MVVM中是否有一个提示要克服这个问题?

最佳答案 另一种不破坏开放/封闭原则的方法是为每种类型的StockItem创建视图模型和视图,然后使用一种类型来整理所有公开的子类型及其相应的视图模型,并提供一种工厂方法获取StockItem并返回匹配的视图模型.

例如,使用IoC容器或MEF很容易做到这一点.

更新

作为使用MEF的简单示例:

public class StockItemEditViewModelFactory : IPartImportsSatisfiedNotification
{
    private Dictionary<Type, IStockItemEditViewModelResolver> resolvers;

    [ImportMany(IStockItemEditViewModelResolver)]
    private IEnumerable<IStockItemEditViewModelResolver> importedResolvers;

    public void OnImportsSatisfied()
    {
        // Build dictionary of StockItem -> StockItemEditViewModel
        // Do error handling if no imported resolvers or duplicate types
        resolvers = new Dictionary<Type, IStockItemEditViewModelResolver>

        foreach(var importedResolver in importedResolvers)
        {
           resolvers.Add(importedResolver.StockItemType, importedResolver);
        }
    }

    public IStockItemEditViewModel Create(StockItem stockItem)
    {
        // Find the appropriate resolver based on stockItem.GetType(), handle errors
        var type = stockItem.GetType();
        var entry = this.resolvers.FirstOrDefault(kv => kv.Key == type);
        var resolver = entry.Value;
        return resolver.CreateEditViewModel(stockItem);
    }
}

[InheritedExport]
public interface IStockItemEditViewModelResolver
{ 
    Type StockItemType { get; } 
    IStockItemEditViewModel CreateEditViewModel(StockItem stockItem);                 
}

public class LotItemEditViewModelResolver : IStockItemEditViewModelResolver
{
    Type StockItemType { get { return typeof(LotItem); } }

    IStockItemEditViewModel CreateEditViewModel(StockItem stockItem)
    {
        return new LotItemEditViewModel(stockItem);
    }
}

public class MainViewModel
{
    public IStockItemEditViewModel ActiveItem { get; private set; }

    public MainViewModel(StockItemEditViewModelFactory editViewModelfactory)
    {
        StockItem stockItem = new LotItem();
        this.ActiveItem = editViewModelFactory.Create(myStockItem);
    }
}

这是未经测试的,但它向您展示了一般方法.您可以使用泛型来使这更整洁.

如果你想使用Unity而不是MEF,那么概念将是相同的,但你需要注册IStockItemEditViewModelResolver的每个实现(或使用Unity扩展并使用约定),然后你的工厂需要一个引用容器,以便它可以做一个ResolveAll(见Unity Resolve Multiple Classes).

点赞