首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WPF TabItem HeaderTemplate

WPF TabItem HeaderTemplate
EN

Stack Overflow用户
提问于 2015-08-25 08:43:53
回答 2查看 27.9K关注 0票数 6

样本代码:

代码语言:javascript
复制
 <TabControl>
    <TabItem>
        <TabItem.Header>
            <StackPanel Orientation="Horizontal" Margin="5">
                <Image Source="/WpfTutorialSamples;component/Images/bullet_blue.png" />
                <TextBlock Text="Blue" Foreground="Blue" />
            </StackPanel>
        </TabItem.Header>
        <Label Content="Content goes here..." />
    </TabItem>
    <TabItem>
        <TabItem.Header>
            <StackPanel Orientation="Horizontal" Margin="5">
                <TextBlock Text="Red" Foreground="Red" />
            </StackPanel>
        </TabItem.Header>
    </TabItem>
    <TabItem>
        <TabItem.Header>
            <StackPanel Orientation="Horizontal" Margin="5">
                <Rectangle Fill="Red" width="20" height="16" />
            </StackPanel>
        </TabItem.Header>
    </TabItem>
</TabControl>

如您所见,TabItem头始终是一个具有不同内容的堆栈面板:

代码语言:javascript
复制
<TabItem.Header>
    <StackPanel Orientation="Horizontal" Margin="5">

    </StackPanel>
</TabItem.Header>

如何将其放入模板中,使我没有重复的堆栈代码?

试着这样做:

代码语言:javascript
复制
<TabControl>
    <TabControl.Resources>
        <Style TargetType="TabItem">
        <Setter Property="HeaderTemplate">
            <Setter.Value>
            <DataTemplate>
            <StackPanel Orientation="Horizontal" Margin="5">
                <ContentPresenter Content="{TemplateBinding ContentControl.Content}"
                            ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"  
                            ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" 
                            HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" 
                            RecognizesAccessKey="True" 
                            SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"  
                            VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}">
                </ContentPresenter>
            </StackPanel>
            </DataTemplate>
            </Setter.Value>
        </Setter>
        </Style>
    </TabControl.Resources>
    <TabItem>
        <TabItem.Header>
            <!-- ??? -->
            <TextBlock Text="X" />
            <TextBlock Text="Y" />
        </TabItem.Header>
</TabControl>

在以下方面的成果:

  • “属性‘头’设置不止一次。”
  • “对象‘对象’已经有一个子对象,不能添加'TextBlock‘。' object’只能接受一个子对象。”
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-25 12:20:31

树头的唯一共同之处就是Margin="5“。在第二和第三标签,堆栈板是不相关的,因为它只有一个孩子。您可以通过使用HeaderTemplate或ItemContainerStyle来实现它:

代码语言:javascript
复制
<TabControl>
    <TabControl.ItemContainerStyle>
        <Style TargetType="TabItem">
            <Setter Property="Padding" Value="5" />
        </Style>
    </TabControl.ItemContainerStyle>

    <TabItem>
        <TabItem.Header>
            <StackPanel Orientation="Horizontal">
                <Image Source="/WpfTutorialSamples;component/Images/bullet_blue.png" />
                <TextBlock Text="Blue" Foreground="Blue" />
            </StackPanel>
        </TabItem.Header>
        <Label Content="Content goes here..." />
    </TabItem>
    <TabItem>
        <TabItem.Header>
            <TextBlock Text="Red" Foreground="Red" />
        </TabItem.Header>
    </TabItem>
    <TabItem>
        <TabItem.Header>
            <Rectangle Fill="Red" Width="20" Height="16" />
        </TabItem.Header>
    </TabItem>
</TabControl>

现在你什么都不重复了。

还可以提取堆栈面板的属性,以避免重复这些属性:

代码语言:javascript
复制
    <TabItem.Header>
        <StackPanel Style="{StaticResource TabHeaderPanel}">
            <Image Source="/WpfTutorialSamples;component/Images/bullet_blue.png" />
            <TextBlock Text="Blue" Foreground="Blue" />
        </StackPanel>
    </TabItem.Header>

    <TabItem.Header>
        <StackPanel Style="{StaticResource TabHeaderPanel}">
            <TextBlock Text="Red" Foreground="Red" />
        </StackPanel>
    </TabItem.Header>

    <TabItem.Header>
        <StackPanel Style="{StaticResource TabHeaderPanel}">
            <Rectangle Fill="Red" width="20" height="16" />
        </StackPanel>
    </TabItem.Header>

如果您想要更多的代码重用,您应该考虑使用类似MVVM的方法:

代码语言:javascript
复制
<TabControl ItemsSource="{Binding Tabs}">
    <TabControl.ItemContainerStyle>
        <Style TargetType="TabItem">
            <Setter Property="HeaderTemplate">
                <Setter.Value>
                    <DataTemplate DataType="local:TabViewModel">

                        <StackPanel Orientation="Horizontal" Margin="5">
                            <Image x:Name="Icon" Source="{Binding Icon, Converter={StaticResource UriToBitmapSourceConverter}}" />
                            <Rectangle x:Name="ColorRect" Height="16" Width="16" Fill="{Binding Color}" Visibility="Collapsed" />
                            <TextBlock Text="{Binding Title}" Foreground="{Binding Color}"/>
                        </StackPanel>

                        <DataTemplate.Triggers>
                            <DataTrigger Binding="{Binding Icon}" Value="{x:Null}">
                                <Setter TargetName="Icon" Property="Visibility" Value="Collapsed" />
                                <Setter TargetName="ColorRect" Property="Visibility" Value="Visible" />
                            </DataTrigger>
                        </DataTemplate.Triggers>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </TabControl.ItemContainerStyle>
</TabControl>

如果不能对所有标头使用单个DataTemplate,则可以使用HeaderTemplateSelector

票数 9
EN

Stack Overflow用户

发布于 2015-08-25 11:51:24

我认为,只有当您绑定Tab集合并动态生成它们时,才会使用HeaderTemplate。如果在ViewModel中设置对象(Header属性是使用隐式DataTemplates的项的集合,可以根据它们的类型生成TextBlocks或矩形),这将有效。

否则,您需要将StackPanel的公共样式设置为使它们都相同并保存重复,或者将TabItem.Header内容的第一个元素设置为从StackPanel派生的自定义控件。

我会自己选择样式路线,除非确实迫切需要从XAML中删除StackPanel行。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32199403

复制
相关文章

相似问题

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