具有MVVM继承的Silverlight:与模型匹配的ModelView和View

时间:2010-04-13 12:47:16

标签: silverlight inheritance mvvm

今天我对Silverlight(4 RC)MVVM和继承概念有一个特殊的问题,并寻找最佳实践解决方案......我认为我理解MVVM背后的基本思想和概念。我的 Model ViewModel 一无所知,因为 ViewModel 本身不知道 View ViewModel 知道模型,而视图知道 ViewModels

想象一下以下基本(示例)场景(我试图保持简短和简单):

我的模型包含一个ProductBase类,其中包含一些基本属性,SimpleProduct : ProductBase添加了一些属性,ExtendedProduct : ProductBase添加了另一个属性。根据这个模型,我有几个ViewModel,最重要的SimpleProductViewModel : ViewModelBaseExtendedProductViewModel : ViewModelBase。最后但并非最不重要的是,根据观看SimpleProductViewExtendedProductView。将来,我可能会添加许多产品类型(以及匹配的视图+虚拟机)。

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中的所有问题也适用。

  

对于我描述的问题,您是否有一些提示甚至解决方案,您希望从我的解释中理解这些问题?

提前谢谢!

托马斯

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>

这里可以使用依赖注入框架来进行查找。

我希望这会有所帮助。