是否有一种MVVM友好的方式来交换视图而不会不必要地激活值转换器?

时间:2010-05-16 20:00:41

标签: c# wpf silverlight xaml mvvm

我认为我正在做的事情就在Josh Smith的MVVM手册之外,但是当视图模型中没有数据发生变化时,我似乎遇到了很多问题,因为值转换器会触发。

所以,我在XAML中定义了ContentControl,如下所示:

<ContentControl Grid.Row="0" Content="{Binding CurrentViewModel}" />

包含此ContentControl的窗口引用了类似这样的资源字典:

<ResourceDictionary ...>
    <DataTemplate DataType="{x:Type lib_vm:SetupPanelViewModel}">
        <lib_v:SetupPanel />
    </DataTemplate>
    <DataTemplate DataType="{x:Type lib_vm:InstructionsPanelViewModel}">
        <lib_v:InstructionsPanel />
    </DataTemplate>
</ResourceDictionary>

因此,基本上,这两个数据模板指定了哪个视图与哪个视图模型一起显示。

每当我窗口的视图模型上的CurrentViewModel属性发生更改时,这会按预期切换视图,但即使没有数据发生更改,它也会导致视图上的值转换器触发。这是IMultiValueConverter类的一个特殊问题,因为value数组中的值设置为DependencyProperty.UnsetValue,除非我专门检查,否则会导致异常。但我也得到了其他奇怪的副作用。

这让我想知道我是否应该手动完成所有操作,例如:

  1. 实例化每个视图。
  2. 将每个视图的DataContext设置为适当的视图模型。
  3. ContentControl提供一个名称并将其公开。
  4. 处理窗口的PropertyChanged事件。
  5. 在事件处理程序中,根据Content(使用ContentControl语句)手动将CurrentViewModel的{​​{1}}属性设置为相应的视图。
  6. 这似乎有效,但它似乎也很不优雅。我希望有更好的方法。

    您能告诉我处理视图切换的最佳方法,以便价值转换器不会不必要地触发吗?

2 个答案:

答案 0 :(得分:1)

您应该查看PRISM或任何其他复合UI框架。棱镜会为你提供一个很好的机制。

答案 1 :(得分:1)

我通过删除所有IValueConverter和IMultiValueConverter类并使用ViewModel提供所有数据来解决这个问题。事实证明,这需要更少的代码和麻烦,并且不会牺牲我所知道的任何东西。