单个选项卡内容的 WPF 选项卡控件覆盖模板
WPF Tab Control override template for individual tab content
我有一个带有一些静态选项卡的选项卡控件。但是我也想动态添加一些额外的标签。因此,我定义了一个 header 模板(使用 TabControl.ItemTemplate)和一个内容模板(使用 TabControl.ContentTemplate)。但是,静态选项卡将显示不同的内容,因此我设置了单个选项卡项的内容模板。但是出于某种原因,我创建的用于设置选项卡内容的项目内容模板也适用于 header.
您可以从随附的屏幕截图和代码中看到,当标签 header 设置为 'Emails' 时,标签内容同时显示在 header 和内容中部分。
如果您需要进一步说明,请告诉我。
<TabControl Name="ResultsTabControl" SelectionChanged="Selector_OnSelectionChanged" Margin="-2,2" SelectedIndex="{Binding SelectedResultsTab, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<TabControl.Resources>
<Style TargetType="TabItem" BasedOn="{StaticResource AccentedMetroTabItemStyle}"></Style>
</TabControl.Resources>
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=Header}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<TextBlock Text="Testing"/>
</DataTemplate>
</TabControl.ContentTemplate>
<TabItem Name="EmailListTab" Header="Emails" Style="{StaticResource AccentedMetroTabItemStyle}">
<TabItem.ContentTemplate>
<DataTemplate>
<TextBlock Text="My Emails Tab"/>
</DataTemplate>
</TabItem.ContentTemplate>
</TabItem>
<Style x:Key="AccentedMetroTabItemStyle" TargetType="{x:Type TabItem}">
<Setter Property="Padding" Value="2 1 2 1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Border x:Name="Border"
HorizontalAlignment="Stretch"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
<StackPanel HorizontalAlignment="Stretch" Orientation="Vertical">
<StackPanel Margin="{TemplateBinding Padding}" Orientation="Horizontal">
<controls1:ContentControlEx x:Name="ContentSite"
Margin="0 2 2 0"
Padding="{TemplateBinding Padding}"
Foreground="{TemplateBinding Foreground}"
FontSize="15"
FontWeight="{TemplateBinding controls1:ControlsHelper.HeaderFontWeight}"
FontStretch="{TemplateBinding controls1:ControlsHelper.HeaderFontStretch}"
Content="{TemplateBinding Header}"
ContentCharacterCasing="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls1:ControlsHelper.ContentCharacterCasing)}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</StackPanel>
<Rectangle x:Name="Underline"
Height="2"
Margin="0 1 0 0"
HorizontalAlignment="Stretch"
Visibility="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TabControl}}, Path=(controls1:TabControlHelper.IsUnderlined), Converter={StaticResource BooleanToVisibilityConverter}}" />
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="ContentSite" Property="TextElement.Foreground" Value="{DynamicResource AccentColorBrush}" />
<Setter TargetName="Underline" Property="Fill" Value="{DynamicResource AccentColorBrush}" />
</Trigger>
<Trigger Property="IsSelected" Value="false">
<Setter TargetName="ContentSite" Property="TextElement.Foreground" Value="{DynamicResource GrayNormalBrush}" />
<Setter TargetName="Underline" Property="Fill" Value="{DynamicResource GrayNormalBrush}" />
</Trigger>
<Trigger SourceName="ContentSite" Property="IsMouseOver" Value="True">
<Setter TargetName="ContentSite" Property="TextElement.Foreground" Value="{DynamicResource GrayHoverBrush}" />
<Setter TargetName="Underline" Property="Fill" Value="{DynamicResource GrayHoverBrush}" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition SourceName="ContentSite" Property="IsMouseOver" Value="True" />
<Condition Property="IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="ContentSite" Property="TextElement.Foreground" Value="{DynamicResource HighlightBrush}" />
<Setter TargetName="Underline" Property="Fill" Value="{DynamicResource HighlightBrush}" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
问题是我们不知道 controls1:ContentControlEx
中会发生什么。
而且基本上您的风格中 header 缺少 ContentPresenter
:
<ContentPresenter x:Name="contentPresenter" ContentSource="Header" Focusable="False" HorizontalAlignment="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
它可能是 controls1:ContentControlEx
的一部分,但你也必须展示它。
我有一个带有一些静态选项卡的选项卡控件。但是我也想动态添加一些额外的标签。因此,我定义了一个 header 模板(使用 TabControl.ItemTemplate)和一个内容模板(使用 TabControl.ContentTemplate)。但是,静态选项卡将显示不同的内容,因此我设置了单个选项卡项的内容模板。但是出于某种原因,我创建的用于设置选项卡内容的项目内容模板也适用于 header.
您可以从随附的屏幕截图和代码中看到,当标签 header 设置为 'Emails' 时,标签内容同时显示在 header 和内容中部分。
如果您需要进一步说明,请告诉我。
<TabControl Name="ResultsTabControl" SelectionChanged="Selector_OnSelectionChanged" Margin="-2,2" SelectedIndex="{Binding SelectedResultsTab, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<TabControl.Resources>
<Style TargetType="TabItem" BasedOn="{StaticResource AccentedMetroTabItemStyle}"></Style>
</TabControl.Resources>
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=Header}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<TextBlock Text="Testing"/>
</DataTemplate>
</TabControl.ContentTemplate>
<TabItem Name="EmailListTab" Header="Emails" Style="{StaticResource AccentedMetroTabItemStyle}">
<TabItem.ContentTemplate>
<DataTemplate>
<TextBlock Text="My Emails Tab"/>
</DataTemplate>
</TabItem.ContentTemplate>
</TabItem>
<Style x:Key="AccentedMetroTabItemStyle" TargetType="{x:Type TabItem}">
<Setter Property="Padding" Value="2 1 2 1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Border x:Name="Border"
HorizontalAlignment="Stretch"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
<StackPanel HorizontalAlignment="Stretch" Orientation="Vertical">
<StackPanel Margin="{TemplateBinding Padding}" Orientation="Horizontal">
<controls1:ContentControlEx x:Name="ContentSite"
Margin="0 2 2 0"
Padding="{TemplateBinding Padding}"
Foreground="{TemplateBinding Foreground}"
FontSize="15"
FontWeight="{TemplateBinding controls1:ControlsHelper.HeaderFontWeight}"
FontStretch="{TemplateBinding controls1:ControlsHelper.HeaderFontStretch}"
Content="{TemplateBinding Header}"
ContentCharacterCasing="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls1:ControlsHelper.ContentCharacterCasing)}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</StackPanel>
<Rectangle x:Name="Underline"
Height="2"
Margin="0 1 0 0"
HorizontalAlignment="Stretch"
Visibility="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TabControl}}, Path=(controls1:TabControlHelper.IsUnderlined), Converter={StaticResource BooleanToVisibilityConverter}}" />
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="ContentSite" Property="TextElement.Foreground" Value="{DynamicResource AccentColorBrush}" />
<Setter TargetName="Underline" Property="Fill" Value="{DynamicResource AccentColorBrush}" />
</Trigger>
<Trigger Property="IsSelected" Value="false">
<Setter TargetName="ContentSite" Property="TextElement.Foreground" Value="{DynamicResource GrayNormalBrush}" />
<Setter TargetName="Underline" Property="Fill" Value="{DynamicResource GrayNormalBrush}" />
</Trigger>
<Trigger SourceName="ContentSite" Property="IsMouseOver" Value="True">
<Setter TargetName="ContentSite" Property="TextElement.Foreground" Value="{DynamicResource GrayHoverBrush}" />
<Setter TargetName="Underline" Property="Fill" Value="{DynamicResource GrayHoverBrush}" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition SourceName="ContentSite" Property="IsMouseOver" Value="True" />
<Condition Property="IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="ContentSite" Property="TextElement.Foreground" Value="{DynamicResource HighlightBrush}" />
<Setter TargetName="Underline" Property="Fill" Value="{DynamicResource HighlightBrush}" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
问题是我们不知道 controls1:ContentControlEx
中会发生什么。
而且基本上您的风格中 header 缺少 ContentPresenter
:
<ContentPresenter x:Name="contentPresenter" ContentSource="Header" Focusable="False" HorizontalAlignment="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
它可能是 controls1:ContentControlEx
的一部分,但你也必须展示它。