首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为WPF TabControl配置动态头

为WPF TabControl配置动态头
EN

Stack Overflow用户
提问于 2020-04-30 20:52:44
回答 1查看 200关注 0票数 0

我试图创建一个使用WPF TabControl来允许用户添加新选项卡的基本窗口。我希望最终产品看起来有点像标签在网页浏览器中的工作方式,而最后一个标签只是一个"+“,点击它就会添加一个新的选项卡。

我试图编写XAML代码来设置它,我发现我可以在"TabControl.Resources“中指定多个TabControl.Resources,并根据"DataType”使用正确的DataTemplate来显示每个选项卡的正确视图.但是,在处理选项卡头时,我只能为“DataTemplate”指定一个TabControl.ItemTemplate

到目前为止,这就是我所拥有的:

代码语言:javascript
运行
复制
<TabControl ItemsSource="{Binding Tabs}">
    <TabControl.Resources>

        <!-- If the tab is of type "TabViewModel" I want this content -->
        <DataTemplate DataType="x:Type vm:TabViewModel">
            <!-- TabView is defined as a separate user control -->
            <v:TabView/>
        </DataTemplate>

        <!-- If the tab is of type "NewTabViewModel" I want this content -->
        <DataTemplate DataType="x:Type vm:NewTabViewModel">
            <!-- NewTabView is defined as a separate user control -->
            <v:NewTabView/>
        </DataTemplate>
    </TabControl.Resources>

    <TabControl.ItemTemplate>
        <!-- if the tab is of type "TabViewModel" I want this header -->
        <DataTemplate DataType="x:Type vm:TabViewModel">
            <TextBlock Text="{Binding Name}"/>
        </DataTemplate>

        <!-- If the tab is of type "NewTabViewModel" I want this header -->
        <!-- ERROR: Adding a second "DataTemplate" here results in an error -->
        <DataTemplate DataType="x:Type vm:NewTabViewModel">
            <TextBlock Text="+"/>
        </DataTemplate>
    </TabControl.ItemTemplate>
</TabControl>

我在谷歌上搜索了一些关于设置TemplateSelector和编写一堆背景C#代码的文章,但对于这么简单的东西,这似乎大大地过分了。我只想让它显示标签名,如果它是一个普通的TabViewModel对象和"+“如果它是一个NewTabViewModel对象。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-30 23:33:46

DataTemplate有两种完全不同的用法。

ItemTemplate属性的类型为DataTemplate。具体来说,是一个DataTemplate,而不是一个集合。它期望您将其设置为所需的任何模板,这就是它将用于填充选项卡标题的内容。此外,在TabControl的情况下,这是将应用于所有标头的模板;您不能在每个选项卡的基础上更改它。

选项卡面板本身是ContentControl类型,每个选项卡都绑定到一个视图模型。ContentControl包含一个ContentPresenter,它遍历逻辑树,查找绑定到的数据类型的DataTemplate (在内部,DataTemplate的DataType属性只是将类型本身设置为x:Key的语法糖)。

您的问题是,您试图像使用ItemTemplate一样使用ResourceDictionary,指定多个DataTemplates,当它期望您自己提供模板时,它只指定一个模板。因此,要实现您想要实现的目标,您需要做的就是给它一个DataTemplate,并用一个ContentPresenter填充它(正如Dreamer所建议的),就像选项卡面板本身所做的那样。这个ContentPresenter有自己的ResourceDictionary,您可以在那里放置标题模板:

代码语言:javascript
运行
复制
<TabControl ItemsSource="{Binding Tabs}">

    <TabControl.Resources>

        <!-- Panel templates -->

        <DataTemplate DataType="{x:Type vm:TabViewModel}">
            <v:TabView />
        </DataTemplate>

        <DataTemplate DataType="{x:Type vm:NewTabViewModel}">
            <v:NewTabView />
        </DataTemplate>
    </TabControl.Resources>

    <TabControl.ItemTemplate>
        <DataTemplate>
            <ContentPresenter Content="{Binding}">
                <ContentPresenter.Resources>

                    <!-- Header templates -->

                    <DataTemplate DataType="{x:Type vm:TabViewModel}">
                        <TextBlock Text="{Binding Name}"/>
                    </DataTemplate>

                    <DataTemplate DataType="{x:Type vm:NewTabViewModel}">
                        <TextBlock Text="+"/>
                    </DataTemplate>

                </ContentPresenter.Resources>
            </ContentPresenter>
        </DataTemplate>
    </TabControl.ItemTemplate>
</TabControl>
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61532527

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档