Silverlight与MVVM继承:模型视图和与模型匹配的视图

Silverlight与MVVM继承:模型视图和与模型匹配的视图,silverlight,inheritance,mvvm,Silverlight,Inheritance,Mvvm,今天我有一个关于Silverlight(4RC)MVVM和继承概念的特别问题,并寻找最佳实践解决方案。。。我认为我理解MVVM背后的基本思想和概念。我的模型对ViewModel一无所知,因为ViewModel本身对视图一无所知。视图模型知道模型,视图知道视图模型 想象一下下面的基本(示例)场景(我尽量简短): 我的模型包含一个带有一些基本属性的ProductBase类,一个SimpleProduct:ProductBase添加更多属性和ExtendedProduct:ProductBase添加其

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

想象一下下面的基本(示例)场景(我尽量简短):

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

1。接收模型集合时,如何知道要创建哪个ViewModel?
调用我的数据提供程序方法后,它最终将拥有一个
列表
。例如,它包含一个SimpleProduct和两个ExtendedProduct。如何将结果转换为
可观察集合
,其中包含适当的ViewModel类型(一个SimpleProductViewModel和两个ExtendedProductViewModels)

I可能检查模型类型并相应地构造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));
    ...
}

……但我认为这是非常糟糕的做法,因为这个代码不遵循面向对象的设计。另一方面,提供抽象工厂方法会将代码减少到:

foreach(ProductBase currentProductBase in resultList)
    viewModels.Add(currentProductBase.CreateViewModel())
并且可以完全扩展,但是由于模型不知道ViewModels,这是不可能的。我可能会在游戏中引入接口,但我还没有看到这种方法被证明是有效的

2。选择ViewModel时,如何知道要显示哪个视图?
这是同样的问题,但在更高的层次上。最终获得所需的
可观察集合
集合需要主视图为ViewModel选择匹配的视图

在WPF中,有一个
DataTemplate
概念,它可以根据定义的数据类型提供视图。不幸的是,这在Silverlight中不起作用,我找到的唯一替代品是SLExtensions工具包的
ResourceSelector
,它有缺陷且不令人满意

除此之外,问题1中的所有问题也适用

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

提前谢谢你


Thomas

我这样做是为了使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);
}
然后,我使用这些来定义实际的具体对象——当然,首先是接口

public interface IPersonModel : IModel
{
}

public interface IPersonViewModel : IViewModel<IPersonModel>
{
}

public interface IPersonView : IView<IPersonViewModel>
{
}
公共接口IPersonModel:IModel { } 公共接口IPersonViewModel:IViewModel { } 公共接口IPersonView:IView { } 注意接口的继承如何在类型关系中锁定

现在可以定义具体的类了

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();
    }
}
公共类PersonModel:ModelBase,IPersonModel
{
}
公共类PersonViewModel:ViewModelBase、IPersonViewModel
{
公共覆盖无效绑定(IPersonModel模型)
{
抛出新的NotImplementedException();
}
}
公共类PersonView:ViewBase、IPersonView
{
公共覆盖无效绑定(IPersonViewModel viewModel)
{
抛出新的NotImplementedException();
}
}
因此,给定一个模型,我可以为该模型查找实现
IViewModel
的对象&给定一个视图模型,我可以为该视图模型查找
IView

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


我希望这能有所帮助。

Enigmativity,非常感谢您的回复,我发现这个基于MVVM的接口实现非常有用。但在最后,对我来说仍然存在差距。。。“Bind(IPersonModel模型)”的基本实现是什么样子的,您能提供更多关于查找接口的具体类的信息吗?(进一步阅读链接?)非常感谢您的支持!(很快我就可以升级投票了,我还是SO新手,很难赢得第一名;-)
Bind(IPersonModel model)
的实现将把模型存储在一个字段中,用作视图模型上与模型相关的属性的支持变量,还将设置所需的任何事件处理程序。对于视图,它还将用于设置与视图模型的实际绑定。
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();
    }
}