在TabControl中使用MahApps.Metro的多视图模型

本文关键字:视图 模型 Metro MahApps TabControl | 更新日期: 2023-09-27 17:59:59

我正试图获得一个TabControl来显示来自两个不同类别/视图模型的数据。基于这两个资源,WPF MahApps.Metro Tabcontrol数据绑定?和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>

我有相应的课程:

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;

我得到的错误是"属性ContentTemplate设置了多次",这有点道理,但在设置ContentTemplate内容之前,我如何对ViewModel类型应用相同类型的检查?

我已经尝试过在ContentTemplate上使用DataType,但不起作用。

PS!当然,我确实希望在每个视图模型中有更多的数据,但这个例子展示了我试图实现的要点。

在TabControl中使用MahApps.Metro的多视图模型

我认为这里的问题是内容模板本身不接受多个模板,这就像当你为一个窗口添加两个网格时,它会告诉你内容属性不能设置多次

从一个基本的角度来看,我能想到的是,你可以做一个单一的模板,它结合了两个模板,并通过触发器和转换器在它们之间进行选择

编辑

检查这篇文章http://tech.pro/tutorial/807/wpf-tutorial-how-to-use-a-datatemplateselector

阅读更多内容后,似乎可以使用ContentTemplateSelector来解决这个问题,尽管我不确定是否存在任何奇怪的依赖关系。

我把我的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>

将以下类添加到我的项目中:

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

这段代码松散地基于UsingContentTemplateSelector,我不确定有什么样的注意事项(如果有的话)。

然而,我确实相信直接使用数据类型的更好的解决方案是可用的,但我不知道怎么做!然而