如何使用DataTemplate + Triggers在视图之间切换

时间:2011-07-01 09:58:55

标签: c# wpf silverlight mvvm datatemplate

我有一个要求,即用户可以切换到以树或数据网格或FlowChart中的文本的形式查看分层数据。

用户可以通过单击切换按钮来执行此操作,切换按钮说明:切换模式。我希望以这样的方式完成所有这些,只有在ViewModel的所有三种情况下都可以在View中处理它。

如何根据触发器将View应用于我的ViewModel。

2 个答案:

答案 0 :(得分:13)

如果要显示的视图的状态保存在某些枚举属性中,您可以使用ContentControlDataTriggers,例如:

<ContentControl>
    <ContentControl.Style>
        <Style TargetType="{x:Type ContentControl}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding ViewMode}" Value="TreeMode">
                    <Setter Property="Content">
                        <Setter.Value>
                            <uc:TreeModeView />
                        </Setter.Value>
                    </Setter>
                </DataTrigger>
                <DataTrigger Binding="{Binding ViewMode}" Value="GridMode">
                    <Setter Property="Content">
                        <Setter.Value>
                            <uc:GridModeView />
                        </Setter.Value>
                    </Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ContentControl.Style>
</ContentControl>

(由于该样式仅在一个地方使用,因此直接将其设置为ContentControl.Style这将有效,如果您想在多个地方使用它,则应设置ContentTemplate,因为否则只有一个视图实例由WPF不允许的样式共享所有控件(当然Content需要设置为某些以供应用的模板) )

当然,您也可以使用ElementName直接绑定到IsChecked的{​​{1}}。相关值将为ToggleButtonTrueFalse

答案 1 :(得分:0)

H.B.的答案很好,但有些情况下它并不是那么好。

如果构建视图(及其基础视图模型)很昂贵,那么每次用户更改视图时,切换Content属性都会支付这笔费用。

在某些情况下,在同一容器中创建两个视图(例如Grid)并切换其Visibility是有意义的。如果在视图模型中使用延迟评估,则在视图变得可见之前不会执行昂贵的操作,并且 - 重要的是 - 它们将仅在视图变得可见的第一时间进行。一旦显示了两个视图,用户就可以在视图之间来回切换而无需重建底层视图模型。

修改

我的立场得到了纠正,有点:H.B。的答案并不像它看起来那么好。

您无法使用样式将Content的{​​{1}}属性设置为ContentControl。有关完整的详细信息,请参阅this blog post,但是如果您使用H.B.的方法,则会遇到运行时错误。

您可以设置UIElement属性,例如:

ContentTemplate