MVVM - 什么应该包含什么...什么应该创造什么

时间:2009-03-16 16:32:02

标签: flex silverlight design-patterns mvvm

我有一个正确的barney让我了解如何使用MVVM模式将所有内容组合在一起。这一切在实践中看起来都很简单但是试图实现它我似乎打破了我尝试编写的各种其他规则。

正如旁注,我正在尝试使用Flex实现模式,而不是使用Silverlight或WPF,所以如果任何人都有充分理由说明为什么不应该这样做,那么我想听听它们。

我有一个问题,我有几个观点。有时我必须同时在页面上显示两个视图;有时候我会切换回一个视图。在我正常的Flex大脑中,我会有一个带有代码隐藏的主视图,其中包含我所有的其他视图(同样具有代码隐藏)。然后,主视图将切换其他单个视图。

当我尝试在MVVM中实现它时,我试图通过使用绑定将MV ViewsViewModels分离来坚持MVVM的原则。假设我为应用程序范围的状态创建ViewModel,我的ApplicationView绑定到该数据并完成所有子视图的切换。

现在,我应该在哪里为子视图创建视图模型?我在ApplicationView内尝试过 - 这似乎不对。然后我在应用程序视图之外尝试并将其实例传递到ApplicationView然后我的子模型绑定到它。我错过了什么吗?这些方法似乎都不适合试图解耦这一点。

非常感谢任何解释此问题的好书或链接。

干杯, 詹姆斯

3 个答案:

答案 0 :(得分:7)

您指的方法是ViewModel组合。它有多个复杂的视图部分需要绑定到自己的ViewModel实体。该方法需要构建具有每个子ViewModel属性的根ViewModel。然后根视图绑定到根视图模型,并且每个视图(无论是显示还是折叠)都绑定到根ViewModel上的相应属性。

ViewModel看起来像这样:

public class RootViewModel 
{
   ChildViewModelA ChildA { get; set; }
   ChildViewModelB ChildB { get; set; }
}

视图看起来像这样:

<Grid>
   <ChildViewA DataContext="{Binding ChildA}" />
   <ChildViewB DataContext="{Binding ChildB}" />
</Grid>

您也可以在此处实现此功能,以便您自己选择一个活动的工作区。

ViewModel看起来像这样:

public class RootViewModel 
{
   public List<ViewModel> ChildWorkspaces { get; set; }
   public ViewModel ActiveWorkspace { get; set; }

   public RootViewModel() 
   {
      ChildWorkspaces.Add(ChildViewModelA);
      ChildWorkspaces.Add(ChildViewModelB);
   }
}

视图看起来像这样:

<Grid>
   <Grid.Resources>
      <DataTemplate DataType="ChildViewModelA">
          <ChildViewA />
      </DataTemplate>
      <DataTemplate DataType="ChildViewModelB">
          <ChildViewB />
      </DataTemplate>
   </Grid.Resources>
   <ContentControl Content="{Binding ActiveWorkspace}" />
</Grid>

这将导致根据ActiveWorkspace中存储的实际对象的类型选择适当的可视化表示。

原谅我的回复是在WPF中。我尽力避免陷入其中的语法: - )

正如您所看到的,多个“ViewModel”可能含糊不清。通常我们发现需要构造多个子实体来适当地构造ViewModel。但是所有ViewModel实体都将位于根视图模型对象中。

在WPF中实现MVVM时,我更倾向于推断隐式应用数据上下文的可视元素(如此响应的后半部分所示)。在更复杂的场景中,我更喜欢使用DataTemplateSelector来执行该决策。但是在超级简单的情况下,您可以在C#/ ActionScript中明确地应用DataContext,或者通过绑定以声明方式应用。

希望这有帮助!

答案 1 :(得分:3)

我已经看到了在几个不同的Flex项目中使用的MVVM方法的变体,但我还没有看到一种对我来说完全正确的方法。也就是说,我认为使用Presentation Models可以使Flex中的测试变得更加容易,所以我很确定会开始围绕这种模式设计更多的应用程序。

我在Flex中实现MVVM的最简单方法是将单个ViewModel放在应用程序Model / ModelLoactor中。 ModelLoactor包含所有全局数据,也可用作所有ViewModels的访问者。然后ApplicationViews可以通过ViewModel绑定到特定ModelLocator,而ViewModels可以通过命令和绑定到其父ModelLocator进行更新。这种方法的一个好处是所有数据逻辑都是本地化的;当然,这也可能被视为一个缺点,由于其对所有ModelLocator的硬编码引用,中心ViewModels变得脆弱。

通过使用Mate框架,我看到了更清晰的方法。 Mate允许更加分散地将ViewModels注入适当的ApplicationViews。 (我想这也可以用Swiz完成,我只是不熟悉那个框架)。通过Mate,每个ApplicationView都会通过Map注入ViewModel。这种方法的优点是如何使用EventMap(ViewModels的Mate版本)更新FrontController。从本质上讲,您的ApplicationViews会调度由一个或多个EventMaps处理的事件,然后这些地图可以对ViewModels中的一个或多个进行更改。此方法允许来自一个ApplicationView的用户手势或事件一次更改多个ViewModels的状态。此外,由于此逻辑被提取到Mate的EventMaps中,因此很容易更改事件的处理方式或更改ViewModels。当然,这种方法的主要缺点是你承诺使用Mate作为框架,根据项目的要求,这可能不是一个选项。

我希望有所帮助!

答案 2 :(得分:0)

我想分享一下我写的MVVM(Silverlight)与PresentionModel(Flex)的比较。它显示了相同模式的两个实现如何不同/比较:

http://houseofbilz.com/archives/2010/12/29/cross-training-in-silverlight-flexmvvm-vs-presentation-model/