用户控件中同一ViewModel的两个视图

时间:2010-12-04 09:01:56

标签: wpf user-controls mvvm datatemplate

我有一个可重复使用的usercontrol,后面有一个viewmodel。我正在尝试在相同数据的不同视图之间切换。目前正尝试在VM上使用Mode属性来完成此任务。

我已经像这样创建了一个DataTemplateSelector:

<UserControl x:Class="MyUserControl">
    <UserControl.Resources>
        <DataTemplate x:Key="ColumnTemplate">
            <StackPanel>
                <Label Text="{Binding Name}"></Label>
                <Label Text="{Binding Address}"></Label>
                <Label Text="{Binding Occupation}"></Label>
            </StackPanel>
        </DataTemplate>
        <DataTemplate x:Key="AvatarTemplate">
            <StackPanel>
                <Image Source="{Binding ProfilePicture}"></Image>
                <Label Text="{Binding Name}"></Label>
            </StackPanel>
        </DataTemplate>
    <local:DisplayTemplateSelector ColumnTemplate="{StaticResource ColumnTemplate}" AvatarTemplate="{StaticResource AvatarTemplate}" x:Key="displayTemplateSelector" />
</UserControl.Resources>
<Grid>
    <ContentControl Name="cpDisplay" Content="{Binding}" ContentTemplateSelector="{StaticResource displayTemplateSelector}" />
</Grid>
</UserControl>

上课:

class DisplayTemplateSelector : DataTemplateSelector
{

    public DataTemplate ColumnTemplate {get;set;}

    public DataTemplate AvatarTemplate {get;set;}

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        MainViewModel vm = (MainViewModel)item;

        switch (vm.Mode)
        {
            case MainViewModel.DisplayMode.Column:
                return ColumnTemplate;
            case MainViewModel.DisplayMode.Avatar:
                return AvatarTemplate;
            default:
                return AvatarTemplate;
        }
    }

}

此用户控件位于MyWindow:

<Grid>
    <controls:MyUserControl x:Name="MyUserControl" DataContext="{Binding}" Margin="0"/>
</Grid>

使用我的viewmodel实例化:

MyWindow w = new MyWindow(_vm);
w.Show();

我遇到的问题是item期间MainViewModel vm = (MainViewModel)item为空。这就像我在数据绑定之前尝试根据数据设置datatemplate?

是否有选择不基于数据对象的所需数据模板 - 但是作为属性或类似用户控件?

3 个答案:

答案 0 :(得分:2)

有很多方法,但这里有一对:

<!-- assumes you have a data template selector implementation available as resource MyContentSelector -->
<ContentControl Content="{StaticResource MainViewModel}" ContentTemplateSelector="{StaticResource MyContentSelector}"/>

或:

<!-- assumes you have appropriate boolean properties on your VM -->
<Grid>
    <ContentControl Content="{StaticResource MainViewModel}" ContentTemplate="{StaticResource column}" Visibility="{Binding IsColumnVisible, Converter={StaticResource BooleanToVisibilityConverter}}"/>
    <ContentControl Content="{StaticResource MainViewModel}" ContentTemplate="{StaticResource avatar}" Visibility="{Binding IsAvatarVisible, Converter={StaticResource BooleanToVisibilityConverter}}"/>
</Grid>

答案 1 :(得分:0)

请参阅DataTemplateSelector类

DataTemplateSelector

答案 2 :(得分:0)

好的,最后通过在usercontrol上使用属性和一些代码来实现我的工作方式:

    public enum DisplayMode
    {
        Column,
        Avatar
    }

    public DisplayMode Mode { get; set; }


    public MyUserControl()
    {
        InitializeComponent();
        Mode = DisplayMode.Avatar;
    }

    private void MyUserControl_Loaded(object sender, RoutedEventArgs e)
    {
        switch (Mode)
        {
            case DisplayMode.Column:
                cpDisplay.ContentTemplate = (DataTemplate)this.Resources["ColumnTemplate"];
                cpDisplay.ApplyTemplate();
                break;
            case DisplayMode.Avatar:
                cpDisplay.ContentTemplate = (DataTemplate)this.Resources["AvatarTemplate"];
                cpDisplay.ApplyTemplate();
                break;
        }
    }

我删除了DataTemplateSelector代码并简单地定义了数据窗口并使用了:

    <ContentPresenter Name="cpDisplay" Content="{Binding}" />