Silverlight 与 MVVM 继承 : ModelView and View matching the Model

标签 silverlight inheritance mvvm

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

想象以下基本(示例)场景(我试图让一切变得简短):

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

<强>1。收到模型集合时我如何知道要创建哪个 ViewModel?
调用我的数据提供程序方法后,它最终会得到 List<ProductBase> 。例如,它包含一个 SimpleProduct 和两个 ExtendedProducts。如何将结果转换为 ObservableCollection<ViewModelBase>其中包含正确的 ViewModel 类型(一个 SimpleProductViewModel 和两个 ExtendedProductViewModel)?

可能检查模型类型并相应地构造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 时如何知道要显示哪个 View?
这是同样的问题,但级别更高。最终终于得到了想要的ObservableCollection<ViewModelBase>集合需要主视图为 ViewModel 选择匹配的 View

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

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

Do you have some hints or even a solution for the problems I describe, which you hopefully can understand from my explanation?

提前谢谢您!

托马斯

最佳答案

我这样做是为了使 MVVM 成为强类型。

我定义了一些基本接口(interface)

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);
}

这提供了我的模型、模型 View 和 View 之间的基本关系。

我为 IModel 创建抽象实现和通用IViewModel<> & IView<>接口(interface)。

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);
}

然后我使用它们来定义实际的具体对象 - 当然首先是接口(interface)。

public interface IPersonModel : IModel
{
}

public interface IPersonViewModel : IViewModel<IPersonModel>
{
}

public interface IPersonView : IView<IPersonViewModel>
{
}

注意接口(interface)的继承如何锁定类型关系。

现在可以定义具体的类了。

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> 的对象对于该模型和给定的 View 模型,我可以查找 IView<VM>对于该 View 模型。

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

我希望这会有所帮助。

关于Silverlight 与 MVVM 继承 : ModelView and View matching the Model,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2629579/

相关文章:

javascript - 对象被 JavaScript 中的后续对象覆盖

c# - MVVM - 从 View 模型关闭一个窗口

java - ZK MVVM 验证消息自动绑定(bind)?

c# - 有谁知道以编程方式轻松将 PDF 转换为 docx 格式的方法

c# - 如何将 TextBlock 居中到给定位置

c# - 亲子关系界面

ios - Swift 符合协议(protocol)子类

silverlight - 如何在 TargetNullValue 属性中绑定(bind)本地化字符串?

c++ - "error:no matching function call to ..."

c# - 如何通过绑定(bind)到复选框来过滤表格项?