【发布时间】:2015-09-02 21:30:38
【问题描述】:
我使用的是视图模型优先方法,在某些模型中,我通过如下界面公开其他模型:
public class ModelA : IModel {}
public class ModelB : IModel {}
// plus yet unknown additional models
public class ViewModelA : IViewModel
{
ViewModelA(ModelA model){}
}
// a model may have several possible view models that should be selectable somehow
public class ViewModelAVariant : IViewModel
{
ViewModelAVariant(ModelA model){}
}
public class ViewModelB : IViewModel {}
{
ViewModelA(ModelB model){}
}
public class ModelContainer
{
public IModel[] SubModels { get { return new IModel { new ModelA(), new ModelB()};}}
}
public class ViewModelContainer
{
private ModelContainer modelContainer;
public IViewModel[] SubModels
{
get
{
return modelContainer.SubModels.Select( sm => ToViewModel(sm)).ToArray();
}
}
private IViewModel ToViewModel(IModel model)
{
// what to insert here?
}
}
可能的解决方案
变体 1:
存储IModel 到IViewModel 转换器的集合并在 ViewModel 中使用它们。
private IDictionary<type,Func<IModel,IViewModel>> converters;
private IViewModel ToViewModel(IModel model)
{
return converters[model.GetType()](model);
}
优点:
- 模型不必知道视图模型
- 可以选择 ViewModels
缺点:
- 如果没有合适的转换器,进程可能会在运行时失败
变体 2:
interface IModel
{
IViewModel ToViewModel();
}
public class ModelA : IModel
{
// this enables view model selection
public ModelA(Func<ModelA,IViewModel> converter)
{
this.converter = converter;
}
private Func<ModelA,IViewModel> converter;
public IViewModel ToViewModel()
{
return converter(this);
}
}
优点:
- 可以选择 ViewModels
- 易于使用,难以误用
缺点:
- 模型必须了解视图模型
我正在寻找没有缺点的变体。
【问题讨论】:
-
请问您为什么要这样做?视图模型应该知道它的模型,没有必要抽象它。而且一个模型不一定与单个视图模型相关,多个视图模型可能使用相同的模型...
-
“模型必须了解视图模型” 有一点是,遵循设计模式成为一种货物崇拜。我认为如果你担心这个,你应该开始用竹子制造飞机。
-
@almulo 我完全同意你的看法。视图模型应该知道它的模型。但我的问题是如何通过模型接口从模型创建视图模型,尤其是当有多个视图模型可供选择时。
-
你...你不能? >_
-
如果你从模型类型自动创建视图模型,很可能你最终得到的视图模型并没有真正做视图模型所做的任何事情(提供整个逻辑),而只是一个(无用的)包装器为模型。通常,您不想基于某些模型的选择来创建视图模型,而是希望显式地创建视图模型(因为您正在构建某些视图),此时视图模型可能会加载一个或多个模型。
标签: c# wpf mvvm model viewmodel