将具有Pivot的页面的视图模型分离为单独的视图模型

时间:2012-11-14 13:52:19

标签: windows-phone-7 mvvm pivot mvvm-light

我正在使用MVVMLight,我创建了标准视图和viewmodel。在视图中我放置了Pivot:

<Grid x:Name="LayoutRoot" Background="Transparent">
    <controls:Pivot Title="MY APPLICATION">
        <local:FirstPivotItem />
        <local:SecondPivotItem />
    </controls:Pivot>
</Grid>

这是我的Pivot项目的样子:

<controls:PivotItem x:Class="Pivot.WindowsPhoneControl1"
    xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
    // standard references and settings
    d:DesignHeight="480" d:DesignWidth="480" Header="First One">

    <Grid x:Name="LayoutRoot">

    </Grid>
</controls:PivotItem>

在代码隐藏

public partial class WindowsPhoneControl1 : PivotItem
{
    public WindowsPhoneControl1() {
        InitializeComponent();
    }
}

我想为此透视图项创建viewmodel,然后像处理标准视图一样使用它。 我会用

<i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectionChanged">
        <mvvm:EventToCommand Command="{Binding PivotChangedCommand}" PassEventArgsToCommand="True" />
    </i:EventTrigger>
</i:Interaction.Triggers>

处理选择更改事件,而不是通过Messanger通知相应的viewmodel。 我不知道如何在Pivot Item类中使用viewmodel的可能性,它继承自PivotItem但不是ViewModelBase,因为我需要。

2 个答案:

答案 0 :(得分:1)

对各个项目使用标准PivotItem控件,并将用户控件放在每个项目中。然后,每个用户控件都可以将其viewmodel作为数据上下文。

 <Grid x:Name="LayoutRoot"
      Background="Transparent">
    <controls:Pivot Title="MY APPLICATION">
        <controls:PivotItem Header="first">
            <local:PivotUserControl1 />
        </controls:PivotItem>

        <controls:PivotItem Header="second">
            <local:PivotUserControl2 />
        </controls:PivotItem>
    </controls:Pivot>
</Grid>

答案 1 :(得分:0)

取决于您是否事先了解枢轴项目或者是否基于数据动态创建它们。我会假设它是第一个,从你到目前为止的判断来判断。

之前我这样做的方法是在父视图模型上有一些PivotItem视图模型作为公共属性,每个视图对应一个。 然后只需将每个PivotItem的dataContext设置为父视图模型上的正确viewmodel属性。

通过这种方式,您可以在没有选择更改事件的情况下离开。 您还可以直接订阅视图模型上的任何事件,因此不一定需要打扰通信消息,因为所有通信都可以通过父视图模型。

第二种方法,如果您事先不确定您将拥有哪些透视项目,那么在父视图模型上有一个PivotItemViewModel集合 - 每个透视项目一个,每个都继承自公共基类或接口。将该集合绑定到viewmodel的ItemSource。

这有点棘手,因为您必须确定要显示的控件,但是如果您将模板存储为某个资源,则可以通过转换器执行此操作:

public class PivotItemToTemplateConverter : IValueConverter
{
    #region IValueConverter Members


    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        switch ((int) value)
        {
            case 1:
                return Application.Current.Resources["Control1Template"];
            case 2:
                return Application.Current.Resources["Control2Template"];
            default:
                return Application.Current.Resources["Control3Template"];
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return null;
    }

    #endregion
}

然后,您可以为枢轴项创建枢轴项模板,并使用转换器根据值获取其中的正确控件。在这种情况下,想象共享基本视图模型有一个属性ViewModelId,它可以有效地识别您感兴趣的控件:

<ContentControl 
                Content="{Binding}"
                ContentTemplate="{Binding ViewModelId,
                                          Converter={StaticResource PivotItemToTemplateConverter }}" />