具有MVVM继承的Silverlight:与模型匹配的ModelView和View [英] Silverlight with MVVM Inheritance: ModelView and View matching the Model

查看:141
本文介绍了具有MVVM继承的Silverlight:与模型匹配的ModelView和View的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Today I have a special question on Silverlight (4 RC) MVVM and inheritance concepts and looking for a best practice solution... I think that i understand the basic idea and concepts behind MVVM. My Model doesn't know anything about the ViewModel as the ViewModel itself doesn't know about the View. The ViewModel knows the Model and the Views know the ViewModels.

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

Imagine the following basic (example) scenario (I'm trying to keep anything short and simple):

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

My Model contains a ProductBase class with a few basic properties, a SimpleProduct : ProductBase adding a few more Properties and ExtendedProduct : ProductBase adding another properties. According to this Model I have several ViewModels, most essential SimpleProductViewModel : ViewModelBase and ExtendedProductViewModel : ViewModelBase. Last but not least, according Views SimpleProductView and ExtendedProductView. In future, I might add many product types (and matching Views + VMs).

1。我如何知道在接收模型集合时要创建哪个ViewModel?

调用我的数据提供者方法后,最终会得到一个 List< ProductBase> 。例如,它包含一个SimpleProduct和两个ExtendedProducts。如何将结果转换为 ObservableCollection< ViewModelBase> 具有正确的ViewModel类型(一个 SimpleProductViewModel 和两个 ExtendedProductViewModels )吗?

1. How do i know which ViewModel to create when receiving a Model collection?
After calling my data provider method, it will finally end up having a List<ProductBase>. It containts, for example, one SimpleProduct and two ExtendedProducts. How can I transform the results to an ObservableCollection<ViewModelBase> having the proper ViewModel types (one SimpleProductViewModel and two ExtendedProductViewModels) in it?

可能检查 Model 类型并构建<相应地,em> 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方法会将代码减少到:

...but I consider this very bad practice as this code doesn't follow the object oriented design. The other way round, providing abstract Factory methods would reduce the code to:

foreach(ProductBase currentProductBase in resultList)
    viewModels.Add(currentProductBase.CreateViewModel())

并且可以完全扩展但是因为模型不知道 ViewModels ,这是不可能的。我可能会在这里将接口带入游戏,但我还没有看到这种方法。

and would be perfectly extensible but since the Model doesn't know the ViewModels, that's not possible. I might bring interfaces into game here, but I haven't seen such approach proven yet.

2。如何知道在选择ViewModel时要显示哪个视图?

这是一个相同的问题,但是在更高的层次上。最终结束了所需的 ObservableCollection< ViewModelBase> 集合需要主视图为 ViewModel View >。

2. How do i know which View to display when selecting a ViewModel?
This is pretty the same problem, but on a higher level. Ended up finally having the desired ObservableCollection<ViewModelBase> collection would require the main view to choose a matching View for the ViewModel.

在WPF中,有一个 DataTemplate 概念,它可以提供 View 在已定义的 DataType 上。不幸的是,这在Silverlight中不起作用,而我发现的唯一替代品是 SLExtensions 工具包的 ResourceSelector ,它是错误的并且不满意。

In WPF, there is a DataTemplate concept which can supply a View upon a defined DataType. Unfortunately, this doesn't work in Silverlight and the only replacement I've found was the ResourceSelector of the SLExtensions toolkit which is buggy and not satisfying.

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

Beside that, all problems from Question 1 apply as well.


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

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

提前谢谢!

Thomas

推荐答案

我这样做是为了让MVVM强类型化。

I do this kind of thing to make MVVM strongly-typed.

我定义了一些基本的接口

I define some basic interfaces

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

这提供了我的模型,模型视图和模型之间的基本关系。视图。

This provides the basic relationships between my models, model views & views.

我为 IModel 和通用 IViewModel<> <创建抽象实现/ code>& 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);
}

然后我用这些来定义实际的具体对象 - 当然首先是接口。

I then use these to define the actual concrete objects - with interfaces first of course.

public interface IPersonModel : IModel
{
}

public interface IPersonViewModel : IViewModel<IPersonModel>
{
}

public interface IPersonView : IView<IPersonViewModel>
{
}

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

Note how the inheritance of the interface locks in the type relationships.

现在可以定义具体的类。

Now the concrete classes can be defined.

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>

So given a model I can look for an object that implements the IViewModel<M> for that model & given a view model I can look for the IView<VM> for that view model.

依赖注入框架可以可以在这里用来查看。

Dependency injection frameworks can be used here to do the look ups.

我希望这会有所帮助。

这篇关于具有MVVM继承的Silverlight:与模型匹配的ModelView和View的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆