今天我对Silverlight(4 RC)MVVM和继承概念有一个特殊的问题,并寻找最佳实践解决方案......我认为我理解MVVM背后的基本思想和概念。我的 Model 对 ViewModel 一无所知,因为 ViewModel 本身不知道 View 。 ViewModel 知道模型,而视图知道 ViewModels 。
想象一下以下基本(示例)场景(我试图保持简短和简单):
我的模型包含一个ProductBase
类,其中包含一些基本属性,SimpleProduct : ProductBase
添加了一些属性,ExtendedProduct : ProductBase
添加了另一个属性。根据这个模型,我有几个ViewModel,最重要的SimpleProductViewModel : ViewModelBase
和ExtendedProductViewModel : ViewModelBase
。最后但并非最不重要的是,根据观看SimpleProductView
和ExtendedProductView
。将来,我可能会添加许多产品类型(以及匹配的视图+虚拟机)。
1。我如何知道在接收模型集合时要创建哪个ViewModel?
在调用我的数据提供者方法之后,它最终会得到List<ProductBase>
。例如,它包含一个SimpleProduct和两个ExtendedProducts。如何将结果转换为具有正确的ViewModel类型(一个 SimpleProductViewModel 和两个 ExtendedProductViewModels )的ObservableCollection<ViewModelBase>
?< / p>
我可能检查模型类型并相应地构建 ViewModel ,即
foreach(ProductBase currentProductBase in resultList)
if (currentProductBase is SimpleProduct)
viewModels.Add(
new SimpleProductViewModel((SimpleProduct)currentProductBase));
else if (currentProductBase is ExtendedProduct)
viewModels.Add(
new ExtendedProductViewModels((ExtendedProduct)currentProductBase));
...
}
...但我认为这是非常糟糕的做法,因为此代码不遵循面向对象的设计。反过来说,提供抽象的Factory方法会将代码减少到:
foreach(ProductBase currentProductBase in resultList)
viewModels.Add(currentProductBase.CreateViewModel())
并且可以完全扩展,但由于 Model 不知道 ViewModels ,这是不可能的。我可能会在这里将界面带入游戏,但我还没有看到这种方法。
2。如何知道选择ViewModel时要显示哪个视图?
这是相同的问题,但在更高的层次上。最后结束使用所需的ObservableCollection<ViewModelBase>
集合需要主视图为 ViewModel 选择匹配的视图。
在WPF中,有一个DataTemplate
概念可以在定义的 DataType 上提供 View 。不幸的是,这在Silverlight中不起作用,而我发现的唯一替代品是 SLExtensions 工具包的ResourceSelector
,它是错误的并且不满意。
除此之外,问题1中的所有问题也适用。
对于我描述的问题,您是否有一些提示甚至解决方案,您希望从我的解释中理解这些问题?
提前谢谢!
托马斯
答案 0 :(得分:3)
我这样做是为了让MVVM强力打字。
我定义了一些基本的接口
public interface IModel
{
}
public interface IViewModel
{
}
public interface IViewModel<M> : IViewModel
where M : IModel
{
void Bind(M model);
}
public interface IView
{
}
public interface IView<VM> : IView
where VM : IViewModel
{
void Bind(VM viewModel);
}
这提供了我的模型,模型视图和模型之间的基本关系。视图。
我为IModel
和通用IViewModel<>
&amp;创建抽象实现IView<>
接口。
public abstract class ModelBase : IModel
{
}
public abstract class ViewModelBase<M> : IViewModel<M>
where M : IModel
{
public abstract void Bind(M model);
}
public abstract class ViewBase<VM> : IView<VM>
where VM : IViewModel
{
public abstract void Bind(VM viewModel);
}
然后我使用它们来定义实际的具体对象 - 当然首先是接口。
public interface IPersonModel : IModel
{
}
public interface IPersonViewModel : IViewModel<IPersonModel>
{
}
public interface IPersonView : IView<IPersonViewModel>
{
}
注意接口的继承如何锁定类型关系。
现在可以定义具体的类。
public class PersonModel : ModelBase, IPersonModel
{
}
public class PersonViewModel : ViewModelBase<IPersonModel>, IPersonViewModel
{
public override void Bind(IPersonModel model)
{
throw new NotImplementedException();
}
}
public class PersonView : ViewBase<IPersonViewModel>, IPersonView
{
public override void Bind(IPersonViewModel viewModel)
{
throw new NotImplementedException();
}
}
因此,给定一个模型,我可以寻找一个实现该模型的IViewModel<M>
的对象。给定一个视图模型,我可以查找该视图模型的IView<VM>
。
这里可以使用依赖注入框架来进行查找。
我希望这会有所帮助。