一千萬個為什麽

搜索

具有MVVM繼承的Silverlight:與模型匹配的ModelView和View

今天我有一個關於Silverlight(4 RC)MVVM和繼承概念的特殊問題,並尋找最佳實踐解決方案......我認為我理解MVVM背後的基本思想和概念。我的 ModelViewModel 一無所知,因為 ViewModel 本身不知道 ViewViewModel 知道模型視圖知道 ViewModels

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

我的模型包含一個帶有一些基本屬性的 ProductBase 類,一個 SimpleProduct:ProductBase 添加了一些屬性, ExtendedProduct:ProductBase 添加了另一個屬性。根據這個模型,我有幾個ViewModel,最重要的 SimpleProductViewModel:ViewModelBaseExtendedProductViewModel:ViewModelBase 。最後但並非最不重要的是,根據Views SimpleProductViewExtendedProductView 。將來,我可能會添加許多產品類型(以及匹配的視圖+ VM)。

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. It containts, for example, one SimpleProduct and two ExtendedProducts. How can I transform the results to an ObservableCollection having the proper ViewModel types (one SimpleProductViewModel and two ExtendedProductViewModels) in it?

可能檢查模型類型並相應地構建 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. 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 collection would require the main view to choose a matching View for the ViewModel.

在WPF中,有一個 DataTemplate 概念,它可以在定義的 DataType 上提供 View 。不幸的是,這在Silverlight中不起作用,我發現的唯一替代是 SLExtensions 工具包的 ResourceSelector ,這是錯誤的並且不令人滿意。

除此之外,問題1中的所有問題也適用。

對於我描述的問題,您是否有一些提示甚至是解決方案,您希望從我的解釋中理解這些問題?

先謝謝你!

托馬斯

最佳答案

我這樣做是為了讓MVVM強力打字。

我定義了一些基本的接口

public interface IModel
{
}

public interface IViewModel
{
}

public interface IViewModel : IViewModel
    where M : IModel
{
    void Bind(M model);
}

public interface IView
{
}

public interface IView : IView
    where VM : IViewModel
{
    void Bind(VM viewModel);
}

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

I create abstract implementations for IModel and the generic IViewModel<> & IView<> interfaces.

public abstract class ModelBase : IModel
{
}

public abstract class ViewModelBase : IViewModel
    where M : IModel
{
    public abstract void Bind(M model);
}

public abstract class ViewBase : IView
where VM : IViewModel
{
    public abstract void Bind(VM viewModel);
}

然後我使用它們來定義實際的具體對象 - 當然首先是接口。

public interface IPersonModel : IModel
{
}

public interface IPersonViewModel : IViewModel
{
}

public interface IPersonView : IView
{
}

請註意接口的繼承如何鎖定類型關系。

現在可以定義具體的類。

public class PersonModel : ModelBase, IPersonModel
{
}

public class PersonViewModel : ViewModelBase, IPersonViewModel
{
    public override void Bind(IPersonModel model)
    {
        throw new NotImplementedException();
    }
}

public class PersonView : ViewBase, IPersonView
{
    public override void Bind(IPersonViewModel viewModel)
    {
        throw new NotImplementedException();
    }
}

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

這裏可以使用依賴註入框架來進行查找。

我希望這有幫助。

轉載註明原文: 具有MVVM繼承的Silverlight:與模型匹配的ModelView和View