在不同的样式中使用相同的 ControlTemplate 并覆盖 属性
Using the same ControlTemplate in different styles and override a property
对于两个 TabItem
我有两个 Style
,它们都使用相同的 ControlTemplate
。现在我希望 styleTabB
显示黄色下划线而不是绿色,但仍然使用 ControlTemplate
。我如何修改 Style
来完成此操作?
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" FontSize="16">
<Window.Resources>
<ControlTemplate x:Key="ctrlTemplate" TargetType="{x:Type TabItem}">
<Grid>
<TextBlock Name="tbTabItemHeaderText"
Text="{TemplateBinding Header}"
Grid.Column="0"
Background="Thistle"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="3,0,0,3">
<TextBlock.TextDecorations>
<TextDecorationCollection>
<TextDecoration Location="Underline"
PenThicknessUnit="Pixel"
PenOffsetUnit="Pixel"
PenOffset="2">
<TextDecoration.Pen>
<Pen Brush="Green" Thickness="4" />
</TextDecoration.Pen>
</TextDecoration>
</TextDecorationCollection>
</TextBlock.TextDecorations>
</TextBlock>
</Grid>
</ControlTemplate>
<!-- Style Tab A -->
<Style x:Key="styleTabA" TargetType="{x:Type TabItem}">
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
<!-- Style Tab B -->
<Style x:Key="styleTabB" TargetType="{x:Type TabItem}">
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
</Window.Resources>
<Grid>
<TabControl Name="tabControl">
<TabItem Name="tabItem_1" Header="--- Tab A ---" Style="{StaticResource styleTabA}"/>
<TabItem Name="tabItem_2" Header="--- Tab B ---" Style="{StaticResource styleTabB}" />
</TabControl>
</Grid>
</Window>
更新
我尝试了 Chris W. 的建议,但根本没有显示下划线:
<ControlTemplate x:Key="ctrlTemplate" TargetType="{x:Type TabItem}">
...
<TextDecoration.Pen>
<Pen Brush="{TemplateBinding Tag}" Thickness="4" />
</TextDecoration.Pen>
...
</ControlTemplate>
<!--Style Tab A-->
<Style x:Key="styleTabA" TargetType="{x:Type TabItem}">
<Setter Property="Tag" Value="Green" />
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
<!--Style Tab B-->
<Style x:Key="styleTabB" TargetType="{x:Type TabItem}">
<Setter Property="Tag" Value="Yellow" />
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
您可以通过针对特定类型在子项中设置子项的样式。这里所有的笔都更新为黄色。
<Style x:Key="styleTabB" TargetType="{x:Type TabItem}">
<Style.Resources>
<Style TargetType="{x:Type Pen}">
<Setter Property="Brush" Value="Yellow"></Setter>
</Style>
</Style.Resources>
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
@CarbineCoder 在大多数情况下都是正确的,但对于您的实例来说,您是对的,并且您从他那里收到的错误是可以预期的,因为 Pen
不是 TargetType。但是,如果我们稍微调整一下以命中 TextDecorations 是 属性 的实际 FrameworkElement,让我们试试这个......并阅读整个内容,因为第一个片段只是一个示例解释。
<Style x:Key="styleTabB" TargetType="{x:Type TabItem}">
<Style.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextDecorations">
<Setter.Value>
<TextDecorationCollection>
<TextDecoration>
<TextDecoration.Pen>
<Pen Brush="Yellow"/>
</TextDecoration.Pen>
</TextDecoration>
</TextDecorationCollection>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
** *Except 这是行不通的,因为您希望已经提供了明确的 属性 值的东西可以从父级继承, 它不是那样工作的。相反,我们引入方便的 Tag
属性(我一直在滥用它)来背负我们的价值,并通过制作一些快速编辑您的 ControlTemplate
赞;
<!-- In your STYLE Template you would want to add a default setter of;
<Setter Property="Tag" Value="Green"/>
-->
<ControlTemplate x:Key="ctrlTemplate" TargetType="{x:Type TabItem}">
<Grid Margin="0,0,0,0">
<TextBlock Name="_tbTabItemHeaderText"
Text="{TemplateBinding Header}"
Grid.Column="0"
Background="Thistle"
VerticalAlignment="Center"
Margin="3,0,0,3">
<TextBlock.TextDecorations>
<TextDecorationCollection>
<TextDecoration Location="Underline"
PenThicknessUnit="Pixel"
PenOffsetUnit="Pixel"
PenOffset="2">
<TextDecoration.Pen>
<Pen Brush="{TemplateBinding Tag}" Thickness="4" />
</TextDecoration.Pen>
</TextDecoration>
</TextDecorationCollection>
</TextBlock.TextDecorations>
</TextBlock>
</Grid>
</ControlTemplate>
现在应该可以点赞了;
<!-- Style Tab A
: This guy should just keep it green IF you applied the default setter mentioned above to the STYLE template -->
<Style x:Key="styleTabA" TargetType="{x:Type TabItem}">
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
<!-- Style Tab B
: This guy should turn it Yellow -->
<Style x:Key="styleTabB" TargetType="{x:Type TabItem}">
<Setter Property="Tag" Value="Yellow"/>
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
我没有时间进行测试,但看起来这应该适合您的场景。希望对你有帮助。
我对 Chris W. 的解决方案做了一点改动,现在可以正常工作了:
<ControlTemplate x:Key="ctrlTemplate" TargetType="{x:Type TabItem}">
...
<TextDecoration.Pen>
<!--Changed next line from <Pen Brush="{TemplateBinding Tag}" Thickness="4" /> to:-->
<Pen Brush="{Binding Path=Tag, RelativeSource={RelativeSource TemplatedParent}}" Thickness="4" />
</TextDecoration.Pen>
...
</ControlTemplate>
<!--Style Tab A-->
<Style x:Key="styleTabA" TargetType="{x:Type TabItem}">
<Setter Property="Tag" Value="Green" />
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
<!--Style Tab B-->
<Style x:Key="styleTabB" TargetType="{x:Type TabItem}">
<Setter Property="Tag" Value="Yellow" />
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
对于两个 TabItem
我有两个 Style
,它们都使用相同的 ControlTemplate
。现在我希望 styleTabB
显示黄色下划线而不是绿色,但仍然使用 ControlTemplate
。我如何修改 Style
来完成此操作?
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" FontSize="16">
<Window.Resources>
<ControlTemplate x:Key="ctrlTemplate" TargetType="{x:Type TabItem}">
<Grid>
<TextBlock Name="tbTabItemHeaderText"
Text="{TemplateBinding Header}"
Grid.Column="0"
Background="Thistle"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="3,0,0,3">
<TextBlock.TextDecorations>
<TextDecorationCollection>
<TextDecoration Location="Underline"
PenThicknessUnit="Pixel"
PenOffsetUnit="Pixel"
PenOffset="2">
<TextDecoration.Pen>
<Pen Brush="Green" Thickness="4" />
</TextDecoration.Pen>
</TextDecoration>
</TextDecorationCollection>
</TextBlock.TextDecorations>
</TextBlock>
</Grid>
</ControlTemplate>
<!-- Style Tab A -->
<Style x:Key="styleTabA" TargetType="{x:Type TabItem}">
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
<!-- Style Tab B -->
<Style x:Key="styleTabB" TargetType="{x:Type TabItem}">
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
</Window.Resources>
<Grid>
<TabControl Name="tabControl">
<TabItem Name="tabItem_1" Header="--- Tab A ---" Style="{StaticResource styleTabA}"/>
<TabItem Name="tabItem_2" Header="--- Tab B ---" Style="{StaticResource styleTabB}" />
</TabControl>
</Grid>
</Window>
更新
我尝试了 Chris W. 的建议,但根本没有显示下划线:
<ControlTemplate x:Key="ctrlTemplate" TargetType="{x:Type TabItem}">
...
<TextDecoration.Pen>
<Pen Brush="{TemplateBinding Tag}" Thickness="4" />
</TextDecoration.Pen>
...
</ControlTemplate>
<!--Style Tab A-->
<Style x:Key="styleTabA" TargetType="{x:Type TabItem}">
<Setter Property="Tag" Value="Green" />
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
<!--Style Tab B-->
<Style x:Key="styleTabB" TargetType="{x:Type TabItem}">
<Setter Property="Tag" Value="Yellow" />
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
您可以通过针对特定类型在子项中设置子项的样式。这里所有的笔都更新为黄色。
<Style x:Key="styleTabB" TargetType="{x:Type TabItem}">
<Style.Resources>
<Style TargetType="{x:Type Pen}">
<Setter Property="Brush" Value="Yellow"></Setter>
</Style>
</Style.Resources>
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
@CarbineCoder 在大多数情况下都是正确的,但对于您的实例来说,您是对的,并且您从他那里收到的错误是可以预期的,因为 Pen
不是 TargetType。但是,如果我们稍微调整一下以命中 TextDecorations 是 属性 的实际 FrameworkElement,让我们试试这个......并阅读整个内容,因为第一个片段只是一个示例解释。
<Style x:Key="styleTabB" TargetType="{x:Type TabItem}">
<Style.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextDecorations">
<Setter.Value>
<TextDecorationCollection>
<TextDecoration>
<TextDecoration.Pen>
<Pen Brush="Yellow"/>
</TextDecoration.Pen>
</TextDecoration>
</TextDecorationCollection>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
** *Except 这是行不通的,因为您希望已经提供了明确的 属性 值的东西可以从父级继承, 它不是那样工作的。相反,我们引入方便的 Tag
属性(我一直在滥用它)来背负我们的价值,并通过制作一些快速编辑您的 ControlTemplate
赞;
<!-- In your STYLE Template you would want to add a default setter of;
<Setter Property="Tag" Value="Green"/>
-->
<ControlTemplate x:Key="ctrlTemplate" TargetType="{x:Type TabItem}">
<Grid Margin="0,0,0,0">
<TextBlock Name="_tbTabItemHeaderText"
Text="{TemplateBinding Header}"
Grid.Column="0"
Background="Thistle"
VerticalAlignment="Center"
Margin="3,0,0,3">
<TextBlock.TextDecorations>
<TextDecorationCollection>
<TextDecoration Location="Underline"
PenThicknessUnit="Pixel"
PenOffsetUnit="Pixel"
PenOffset="2">
<TextDecoration.Pen>
<Pen Brush="{TemplateBinding Tag}" Thickness="4" />
</TextDecoration.Pen>
</TextDecoration>
</TextDecorationCollection>
</TextBlock.TextDecorations>
</TextBlock>
</Grid>
</ControlTemplate>
现在应该可以点赞了;
<!-- Style Tab A
: This guy should just keep it green IF you applied the default setter mentioned above to the STYLE template -->
<Style x:Key="styleTabA" TargetType="{x:Type TabItem}">
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
<!-- Style Tab B
: This guy should turn it Yellow -->
<Style x:Key="styleTabB" TargetType="{x:Type TabItem}">
<Setter Property="Tag" Value="Yellow"/>
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
我没有时间进行测试,但看起来这应该适合您的场景。希望对你有帮助。
我对 Chris W. 的解决方案做了一点改动,现在可以正常工作了:
<ControlTemplate x:Key="ctrlTemplate" TargetType="{x:Type TabItem}">
...
<TextDecoration.Pen>
<!--Changed next line from <Pen Brush="{TemplateBinding Tag}" Thickness="4" /> to:-->
<Pen Brush="{Binding Path=Tag, RelativeSource={RelativeSource TemplatedParent}}" Thickness="4" />
</TextDecoration.Pen>
...
</ControlTemplate>
<!--Style Tab A-->
<Style x:Key="styleTabA" TargetType="{x:Type TabItem}">
<Setter Property="Tag" Value="Green" />
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
<!--Style Tab B-->
<Style x:Key="styleTabB" TargetType="{x:Type TabItem}">
<Setter Property="Tag" Value="Yellow" />
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>