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

发布于 2024-10-06 15:08:08 字数 2315 浏览 1 评论 0原文

我有一个可重用的用户控件,其背后有一个视图模型。我正在尝试在同一数据的不同视图之间切换。目前正在尝试使用虚拟机上的模式属性来完成此操作。

我创建了一个 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>

它是用我的视图模型实例化的:

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

我遇到的问题是 itemMainViewModel vm = ( MainViewModel)项目。就像我试图在绑定数据之前根据数据设置数据模板?

无论如何,是否可以选择不基于数据对象的所需数据模板 - 而是作为用户控件上的属性或类似属性?

I have a re-usable usercontrol with a viewmodel behind it. I'm trying to switch between different views of the same data. Currently trying to use a Mode property on the VM to accomplish this.

I've created a DataTemplateSelector like so:

<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>

With the class:

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;
        }
    }

}

This usercontrol sits in MyWindow:

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

Which is instantiated with my viewmodel:

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

The problem I have is that item is null during MainViewModel vm = (MainViewModel)item. It's like I'm trying to set the datatemplate based on data, before the data is bound?

Is there anyway to choose the desired datatemplate not based on the dataobject - but as a property or similar on the usercontrol?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

維他命╮ 2024-10-13 15:08:08

方法有很多,但这里有几种:

<!-- 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>

There are many ways, but here are a couple:

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

or:

<!-- 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>
黎夕旧梦 2024-10-13 15:08:08

请参阅 DataTemplateSelector 类

DataTemplateSelector

See DataTemplateSelector Class

DataTemplateSelector

无名指的心愿 2024-10-13 15:08:08

好的,终于通过使用用户控件上的属性和后面的一些代码来按照我需要的方式工作:

    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}" />

Ok, finally got this to work how I needed by using a property on the usercontrol and some code behind:

    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;
        }
    }

I removed the DataTemplateSelector code and simply defined the datatemplates and used:

    <ContentPresenter Name="cpDisplay" Content="{Binding}" />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文