如何使用绑定使WPF TabItem的标题出现?

时间:2009-02-24 23:55:56

标签: c# wpf xaml

我正在创建一个用户界面,其中TabControl有一系列标准TabItem,其中包含普通的WPF控件作为其内容。标题只是像往常一样显示普通字符串。但是,我希望最后一项的标题包含Button而不是普通字符串。

让我强调我已经知道如何在没有绑定的情况下做到这一点。我想用绑定来做。具体来说,TabControl绑定到UserControl的数组,除了最后一个Button对象。我希望这个Button出现在标题中,而不是最后一个TabItem的内容。 (坦率地说,我不关心最后TabItem的内容是什么。只有标题。)

我了解DataTemplateSelectorStyleSelector s。我无法弄清楚的是样式和模板的组合将为我做什么。 具体来说,我需要知道最后一项的StyleDataTemplate应该是什么样的,以便我可以适当地选择它们。不需要显示其他代码。

3 个答案:

答案 0 :(得分:1)

我自己想通了。我是WPF / XAML的新手,我刚才的见解是,在像TabControl这样的ItemsControl的情况下,DataTemplate列出了每个项目的内容,但没有说明整体项目本身的布局,由ControlTemplate管理。现在我意识到我根本不需要DataTemplateSelector,只是最后一项的样式,如下所示:


            <Style x:Key="buttonStyle" TargetType="TabItem">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="TabItem">
                            <Border>
                                <ContentPresenter
                                    Margin="4,1,0,1"
                                    Content="{Binding}"
                                    ContentSource="Header">
                                </ContentPresenter>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>


答案 1 :(得分:0)

我要尝试的第一件事是设置最后一个 TabItem 的样式。在样式中,如果将 Header 属性绑定到 Content 属性,该属性应使按钮显示在TabItems标头中。然后,您将需要一个对项目不可见的DataTemplate,以便您不会在选项卡的内容区域中看到它。

如果它不起作用,那么您可能需要为选项卡项创建一个新的ControlTemplate。默认模板如下所示:

<Grid SnapsToDevicePixels="true">
<Border Name="Bd" Padding="{TemplateBinding Padding}" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" BorderThickness="1,1,1,0">
    <ContentPresenter Name="Content" 
            ContentSource="Header" 
            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
            RecognizesAccessKey="true" 
            HorizontalAlignment="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" 
                VerticalAlignment="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
</Border>

您唯一需要更改的是从标题内容的ContentSource。你应该创建原件的副本来执行此操作,否则你将错过所有相关的触发器。您可以使用反射器的BAML查看器扩展来查找原件。或者如果有的话,你可以在Blend中获得原版。

答案 2 :(得分:0)

还有另一种方法可以做到更好。

<TabControl>
    <TabControl.ItemsSource>
        <CompositeCollection>
        <CollectionContainer Collection="{StaticResource items}" />
            <TabItem>
            <TabItem.Template>
                    <ControlTemplate>
                        <Border Name="PART_Header" Margin="4,0,1,1">                                    
                            <Button Click="AddTicket">Add Ticket</Button>
                    </Border>
                </ControlTemplate>
                </TabItem.Template>
            </TabItem>
        </CompositeCollection>
    </TabControl.ItemsSource>
</TabControl>

(请注意,以上内容完全是从内存中完成的。我使用Mac并且不想为此启动我的VM。它应该相当准确。)