简体   繁体   English

TabControl中带有MahApps.Metro的多视图模型

[英]Multiple view models with MahApps.Metro within TabControl

I'm trying to get a TabControl to displays holding data from two different categories/viewmodels. 我试图获取一个TabControl来显示来自两个不同类别/视图模型的保存数据。 Based on these two resources, WPF MahApps.Metro Tabcontrol data bound? 基于这两个资源, WPF MahApps.Metro Tabcontrol数据绑定了吗? and DataTemplates aren't applied , I tried the following which doesn't quite make the cut as it gives an compilation error. 未应用DataTemplates ,我尝试了以下方法,因为它给出了编译错误,因此并不能很好地进行剪切。

<TabControl ItemsSource="{Binding Collection}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Title}" />
        </DataTemplate>
    </TabControl.ItemTemplate>
    <TabControl.ContentTemplate>
        <DataTemplate DataType="{x:Type viewModels:SubViewModelAlpha}">
            <TextBlock>SubViewModelAlpha</TextBlock>
        </DataTemplate>
        <DataTemplate DataType="{x:Type viewModels:SubViewModelBeta}">
            <TextBlock>SubViewModelBeta</TextBlock>
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>

I have the corresponding classes: 我有相应的类:

public class ViewModel { 
   public string Title { get; set; }
}

public class SubViewModelAlpha : ViewModel { }
public class SubViewModelBeta : ViewModel { }

// In another class, I have this property ... 
public ObservableColletion<ViewModel> Collection {
   get { return _collection; } 
}
// ... and this list
private ObservableColletion<ViewModel> _collection;

The error I get is "Property ContentTemplate is set more than once", which kind of make sense, but how can I apply the same type of checking against a type of ViewModel before setting the ContentTemplate stuff? 我收到的错误是“属性ContentTemplate设置不止一次”,这是有道理的,但是在设置ContentTemplate内容之前,如何在ViewModel类型上应用相同类型的检查呢?

I have already tried using the DataType on the ContentTemplate but that doesn't work. 我已经尝试过在ContentTemplate上使用DataType ,但这不起作用。

PS! PS! I do of course want much more data within each viewmodel, but this example shows the gist of what I'm trying to achieve. 当然,我确实希望每个视图模型中有更多的数据,但是此示例显示了我要实现的目标。

the problem here i think is that the content template it self doesn't accept more than a single template , it's like when you add two grids for a single window it will tell you that the content property can't be set more than once 我认为这里的问题是它自己的内容模板不接受单个模板,就像您为单个窗口添加两个网格时,它会告诉您content属性不能设置多次

what i can think of here from a basic prospective is that you can do a single template that combines both template and choose between them by triggers and converters 从基本的角度来看,我可以想到的是,您可以将单个模板组合在一起,并通过触发器和转换器在它们之间进行选择

Edit 编辑

check this article http://tech.pro/tutorial/807/wpf-tutorial-how-to-use-a-datatemplateselector 检查本文http://tech.pro/tutorial/807/wpf-tutorial-how-to-use-a-datatemplateselector

After reading some more, it seems like the issue can be solved using a ContentTemplateSelector, albeit I'm not sure if there are any strange dependcies going on. 阅读更多内容之后,似乎可以使用ContentTemplateSelector来解决问题,尽管我不确定是否存在任何奇怪的依赖关系。

I changed my xaml to look like: 我将xaml更改为:

<TabControl ItemsSource="{Binding Collection}"
            ContentTemplateSelector="{DynamicResource MyContentTemplateSelector}">
    <TabControl.Resource>
        <DataTemplate x:Key="BetaTemplate" DataType="{x:Type viewModels:SubViewModelAlpha}">
            <TextBlock>SubViewModelAlpha</TextBlock>
        </DataTemplate>
        <DataTemplate x:Key="BetaTemplate" DataType="{x:Type viewModels:SubViewModelBeta}">
            <TextBlock>SubViewModelBeta</TextBlock>
        </DataTemplate>
        <viewModels:MyContentTemplateSelector
            x:Key="MyContentTemplateSelector" 
            AlphaTemplate="{StaticResource AlphaTemplate}"
            BetaTemplate="{StaticResource BetaTemplate}" />
    <TabControl.Resource>
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Title}" />
        </DataTemplate>
    </TabControl.ItemTemplate>
</TabControl>

With the following class added to my project: 将以下课程添加到我的项目中:

public class MyContentTemplateSelector : DataTemplateSelector
{
    public DataTemplate AlphaTemplate { get; set; }
    public DataTemplate BetaTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item is SubViewModelAlpha) 
            return AlphaTemplate;

        if (item is SubViewModelBeta)
            return BetaTemplate;

        return base.SelectTemplate(item, container);
    }
}

This code is loosely based on Using ContentTemplateSelector , and I'm not sure what kind of caveats there are, if any. 这段代码大致基于Using ContentTemplateSelector ,我不确定有什么警告(如果有的话)。

I do however believe an even nicer solution directly using the data type is availabe, but I don't know how! 但是,我确实相信可以使用直接使用数据类型的更好解决方案,但是我不知道该怎么做! Yet... 然而...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM