MVVM - 决定哪个ViewModel负责什么

时间:2010-08-25 08:04:00

标签: mvvm mvvm-light

我有一个简单的应用程序,包括:

模型

  • 产品
  • 应用于该项目列表的过滤条件

视图

  • WelcomePage
  • MainItemsPage
  • FilterEditPage

我正在使用MVVM Light和Windows Phone 7

我目前有3个ViewModel,每个View一个。在过去,我有一个单一的ViewModel,这使得我即将要求的通信很容易。但是我想要使用3个单独的VM,因为这似乎是正确的方法。

WelcomePage能够在导航到MainItemsPage之前设置其中一个过滤条件。 MainItemsPage绑定到由其ViewModel公开的Items属性。 ViewModel需要根据当前筛选条件筛选该列表。 FilterEditPage允许用户编辑4个变量的完整标准集。更改条件后,需要重新过滤ViewModel for MainItemsPage中使用的Items集合。

问题是我如何通过应用程序传递过滤器更改。我知道MVVM具有Messaging的概念,而MVVM Light工具包提供了Messenger类。然而,我正在努力的是发送这些消息的责任在哪里?

  1. 当需要使用当前过滤器集时,3个VM是否会转到模型?
  2. 是否所有过滤器更新都通过FilterEditViewModel,然后广播过滤器更改消息?
  3. 我是否会为所有视图返回单个VM?
  4. 我无法看到1.工作,因为某些东西需要触发VM返回模型 我知道我现在可以顺利工作,没有任何问题。这是错的吗?

    TIA

    Pat Long

2 个答案:

答案 0 :(得分:0)

在您的方案中,三个VM是正确的方法。我建议你在你的虚拟机之间建立一个父/子关系。由于MainVM保存ItemList,因此这是应用FilterChanges的位置。 FilterEditVM仅接收过滤器更改而不是调用MainVM,它必须重新应用过滤器。

结构将是这样的:

public class WelcomePageVM
{
    public WelcomePageVM()
    {
        this.FilterEditPageVM = new FilterEditPageVM(this);
        this.MainItemsVM = new MainItemsVM(this);
    }

    public FilterEditPageVM FilterEditPageVM { get; private set; }

    public MainItemsVM MainItemsVM { get; private set; }

    public void SetInitialFilter1(object filter)
    {
        // the initial filter
        this.FilterEditPageVM.Filter1Value = filter;
        this.MainItemsVM.ApplyFilters();
    }
}

public class FilterEditPageVM : ChildViewModelBase<WelcomePageVM>
{
    public FilterEditPageVM(WelcomePageVM parent)
        : base(parent) { }

    public object Filter1Value { get; set; }
    public object Filter2Value { get; set; }
    public object Filter3Value { get; set; }
    public object Filter4Value { get; set; }

    public void FinishFilterChange()
    {
        this.Parent.MainItemsVM.ApplyFilters();
    }
}

public class MainItemsVM : ChildViewModelBase<WelcomePageVM>
{
    public MainItemsVM(WelcomePageVM parent)
        : base(parent) { }

    public List<object> ItemList { get; set; }

    public void ApplyFilters()
    {
        // filter apply logic
    }
}

public abstract class ChildViewModelBase<T>
{
    T _parent;

    public ChildViewModelBase(T parent)
    {
        this._parent = parent;
    }

    public T Parent { get { return _parent; } }
}

在这里你可以访问所有的视图模型,这是可以的,因为你保持在“控制器”级别。

答案 1 :(得分:0)

我会将共享当前过滤器放在模型而不是视图模型中。您可能在不同页面或同一页面上有很多viewModel(考虑显示当前选择的面包屑以及需要显示过滤器的其他内容)。

视图模型可以订阅的过滤器的单例模型怎么样?