WPF TabItem HeaderTemplate [英] WPF TabItem HeaderTemplate

查看:37
本文介绍了WPF TabItem HeaderTemplate的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

示例代码:

 <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 Header 始终是一个包含不同内容的堆栈面板:

As you can see, the TabItem Header is Always a stackpanel with different content:

<TabItem.Header>
    <StackPanel Orientation="Horizontal" Margin="5">

    </StackPanel>
</TabItem.Header>

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

How can you put this in a template so that I don't have duplicate stackpanel code?

尝试这样做:

<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>

结果:

  • 属性 'Header' 设置了不止一次."
  • 对象‘Object’已经有一个孩子,不能添加‘TextBlock’.‘Object’只能接受一个孩子."

推荐答案

树标题真正共有的唯一内容是 Margin="5".在第二个和第三个选项卡中,堆栈面板无关紧要,因为它只有一个子项.您可以使用 HeaderTemplate 或 ItemContainerStyle 来实现它:

The only thing the tree headers really have common is the Margin="5". In second and third tab the stackpanel is irrelavant, because it has only one child. You can achive it either by using HeaderTemplate or ItemContainerStyle:

<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>

现在你不要重复任何事情.

now you don't repeat anything.

您还可以将 stackpanel 的属性提取到样式以避免重复它们:

You could also extract the properties of stackpanel to style to avoid repeating them:

    <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 的方法:

If you want even more code reuse, you should consider MVVM-like approach:

<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

if you can't use single DataTemplate for all headers, you can use HeaderTemplateSelector

这篇关于WPF TabItem HeaderTemplate的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆