【问题标题】:Using the same ControlTemplate in different styles and override a property以不同的样式使用相同的 ControlTemplate 并覆盖一个属性
【发布时间】:2016-03-11 11:09:42
【问题描述】:

对于两个TabItems,我有两个Styles,都使用相同的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>

【问题讨论】:

    标签: wpf xaml styles tabcontrol controltemplate


    【解决方案1】:

    您可以通过定位特定类型来设置子元素的样式。这里所有的 Pen 都更新为黄色。

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

    【讨论】:

    • 不工作,得到消息“Type Pen 必须是 FrameworkElement 或 FrameworkContentElement 的派生”。
    【解决方案2】:

    @CarbineCoder 在大多数情况下都是正确的,但对于您的情况,您是对的,并且您从他那里收到的错误是预料之中的,因为Pen 不是 TargetType。但是,如果我们稍微调整一下以达到 TextDecorations 是其属性的实际 FrameworkElement,让我们试试这个……并阅读整个内容,因为第一个 sn-p 只是一个示例说明。

    <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 属性(我一直滥用它)来利用我们的价值,并允许通过对您的@987654324 进行一些快速编辑来与我们的伙伴交谈。 @喜欢;

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

    我没有时间进行测试,但看起来这应该适合您的场景。希望对您有所帮助。

    【讨论】:

    • 我第一次尝试时无法正常工作,根本没有显示下划线。我明天再来。
    • 第一个sn-p只是为了解释。您需要在样式模板上设置默认值,而不是在控件模板上。如果我有时间,我会实际测试它,因为我在没有先确认的情况下提交一些东西是一种愚蠢的举动……但现在是星期五。 :)
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-13
      • 1970-01-01
      • 2014-12-13
      • 1970-01-01
      • 2014-03-12
      • 2013-06-10
      • 2018-08-31
      相关资源
      最近更新 更多