在不同的样式中使用相同的ControlTemplate并覆盖属性

时间:2016-03-11 11:09:42

标签: wpf xaml styles tabcontrol controltemplate

enter image description here

对于两个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>

3 个答案:

答案 0 :(得分:1)

您可以通过定位特定类型来设置子项中子项的样式。这里所有笔都用黄色更新。

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

答案 1 :(得分:1)

@CarbineCoder对于大多数情况都是正确的,但对于您的实例,您是正确的,并且由于Pen不是TargetType,因此您将收到他的错误。但是,如果我们稍微调整一下来点击实际的FrameworkElement,其中TextDecorations是一个属性,让我们试试这个...并阅读整个内容,因为第一个代码片段只是一个示例解释。

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

** *除之外不能正常工作,因为您希望某些内容已经提供了从父级继承的显式属性值,并且它无法正常工作。相反,我们带来了方便的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>

我没有时间进行测试,但似乎这应该适用于您的方案。希望它有所帮助。

答案 2 :(得分:1)

enter image description here

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