如何通过TabControl模板控制Textblock属性
How to control Textblock properties through TabControl template
我设置了一个带有自定义网格的 TabControl
来放置图片,并设置了一个 Textblock
object 作为 headers (TabItem
) 的设计.我目前正在使用模板控制 headers 的背景颜色,但我无法弄清楚如何使用相同的模板来控制嵌入式 TextBlock
的 Foreground
颜色。
我是一个新手 Visual Studio C# 人,但我对这些模板的理解是我也可以使用它们来设置 child 属性(有点类似于 CSS child 选择器)?还是我完全离开了?
这是我的 "design" -- 您会注意到顶部带有自定义样式的三个选项卡:
我当前的 TabItem
模板
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid x:Name="Root">
<Border x:Name="Border" Margin="0,0,-4,0">
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header"
Margin="12,2,12,2"
RecognizesAccessKey="True" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<!-- Selected color -->
<Trigger Property="IsSelected" Value="True">
<!-- <Setter Property="TextElement.Foreground" TargetName="ContentSite" Value="White"/>-->
<Setter Property="Panel.ZIndex" Value="100" />
<Setter TargetName="Border" Property="Background" Value="#FFEF690D" />
</Trigger>
<!-- Not Selected color -->
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="Border" Property="Background" Value="#FFEE8740" />
</Trigger>
<!-- Tab mouseovers-->
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/>
<Condition Property="IsSelected" Value="False"/>
</MultiTrigger.Conditions>
<Setter TargetName="Border" Property="Background" Value="#FFEFA470" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
我当前 xaml 的 TabControl
设置(为简洁起见,减去第三个 TabItem
)
<TabControl x:Name="tabControl" HorizontalAlignment="Left" Height="311" Margin="0" VerticalAlignment="Top" Width="717" Background="#FFF9F9F9" Style="{DynamicResource MainMenuTabs}">
<TabItem Background="{x:Null}" BorderBrush="{x:Null}" Foreground="{x:Null}">
<!-- TAB 1 -->
<TabItem.Header>
<Grid x:Name="Main" Margin="0" Height="52" Width="166">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="52"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="textBlock" Margin="0,5,0,3" TextWrapping="Wrap" Foreground="White" FontSize="36" Grid.Column="1" d:LayoutOverrides="Width" VerticalAlignment="Bottom"><Run Text="Main"/></TextBlock>
<Image x:Name="icons_server_32_png" Margin="10,0,10,10" Source="icons/server-32.png" Stretch="Fill" Height="32" VerticalAlignment="Bottom"/>
</Grid>
</TabItem.Header>
<Grid Background="#FFE5E5E5"/>
</TabItem>
<TabItem>
<!-- TAB 2 -->
<TabItem.Header>
<Grid x:Name="Backups" Margin="0" Height="52" Width="216">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="52"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="textBlock1" Margin="0,5,0,3" TextWrapping="Wrap" Foreground="White" FontSize="36" Grid.Column="1" d:LayoutOverrides="Width" VerticalAlignment="Bottom" Text="Backups"/>
<Image x:Name="icons_server_32_png1" Margin="10,0,10,10" Source="icons/magnifier-tool.png" Stretch="Fill" Height="32" VerticalAlignment="Bottom"/>
</Grid>
</TabItem.Header>
<Grid Background="#FFE5E5E5"/>
</TabItem>
</TabControl>
我建议使用 LinqToVisualTree ...
http://blog.scottlogic.com/2010/03/04/linq-to-visual-tree.html
您可以在 TabControl 中找到所有 "textBlock" 控件,如下所示:
tabControl.Descendants<TextBlock>().Where(d => d.Name=="textBlock");
然后您将可以控制 TextBlock 属性
对于任何试图完成同类任务的人,有一种方法可以参考父资源并"query"它们以获取信息。
我没有在 TabItem
上放置触发器来更改字体的颜色,而是在引用 TabItem
状态的 TextBlock
上放置触发器。
您最终会使用 DataTrigger
并使用 RelativeSource
设置绑定它。在我的例子中,我用 {RelativeSource AncestorType={x:Type TabItem}}}
将它绑定到 TabItem
这是我应用到 TextBlock
控件的 XAML 样式:
<Style x:Key="HeaderTextStyle" TargetType="{x:Type TextBlock}">
<Setter Property="TextWrapping" Value="NoWrap"/>
<Setter Property="TextTrimming" Value="None"/>
<Setter Property="Foreground" Value="{StaticResource HeaderTextColor_NotSelected}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type TabItem}}}" Value="true">
<Setter Property="Foreground" Value="{StaticResource HeaderTextColor}"/>
</DataTrigger>
</Style.Triggers>
</Style>
我设置了一个带有自定义网格的 TabControl
来放置图片,并设置了一个 Textblock
object 作为 headers (TabItem
) 的设计.我目前正在使用模板控制 headers 的背景颜色,但我无法弄清楚如何使用相同的模板来控制嵌入式 TextBlock
的 Foreground
颜色。
我是一个新手 Visual Studio C# 人,但我对这些模板的理解是我也可以使用它们来设置 child 属性(有点类似于 CSS child 选择器)?还是我完全离开了?
这是我的 "design" -- 您会注意到顶部带有自定义样式的三个选项卡:
我当前的 TabItem
模板
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid x:Name="Root">
<Border x:Name="Border" Margin="0,0,-4,0">
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header"
Margin="12,2,12,2"
RecognizesAccessKey="True" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<!-- Selected color -->
<Trigger Property="IsSelected" Value="True">
<!-- <Setter Property="TextElement.Foreground" TargetName="ContentSite" Value="White"/>-->
<Setter Property="Panel.ZIndex" Value="100" />
<Setter TargetName="Border" Property="Background" Value="#FFEF690D" />
</Trigger>
<!-- Not Selected color -->
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="Border" Property="Background" Value="#FFEE8740" />
</Trigger>
<!-- Tab mouseovers-->
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/>
<Condition Property="IsSelected" Value="False"/>
</MultiTrigger.Conditions>
<Setter TargetName="Border" Property="Background" Value="#FFEFA470" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
我当前 xaml 的 TabControl
设置(为简洁起见,减去第三个 TabItem
)
<TabControl x:Name="tabControl" HorizontalAlignment="Left" Height="311" Margin="0" VerticalAlignment="Top" Width="717" Background="#FFF9F9F9" Style="{DynamicResource MainMenuTabs}">
<TabItem Background="{x:Null}" BorderBrush="{x:Null}" Foreground="{x:Null}">
<!-- TAB 1 -->
<TabItem.Header>
<Grid x:Name="Main" Margin="0" Height="52" Width="166">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="52"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="textBlock" Margin="0,5,0,3" TextWrapping="Wrap" Foreground="White" FontSize="36" Grid.Column="1" d:LayoutOverrides="Width" VerticalAlignment="Bottom"><Run Text="Main"/></TextBlock>
<Image x:Name="icons_server_32_png" Margin="10,0,10,10" Source="icons/server-32.png" Stretch="Fill" Height="32" VerticalAlignment="Bottom"/>
</Grid>
</TabItem.Header>
<Grid Background="#FFE5E5E5"/>
</TabItem>
<TabItem>
<!-- TAB 2 -->
<TabItem.Header>
<Grid x:Name="Backups" Margin="0" Height="52" Width="216">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="52"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="textBlock1" Margin="0,5,0,3" TextWrapping="Wrap" Foreground="White" FontSize="36" Grid.Column="1" d:LayoutOverrides="Width" VerticalAlignment="Bottom" Text="Backups"/>
<Image x:Name="icons_server_32_png1" Margin="10,0,10,10" Source="icons/magnifier-tool.png" Stretch="Fill" Height="32" VerticalAlignment="Bottom"/>
</Grid>
</TabItem.Header>
<Grid Background="#FFE5E5E5"/>
</TabItem>
</TabControl>
我建议使用 LinqToVisualTree ...
http://blog.scottlogic.com/2010/03/04/linq-to-visual-tree.html
您可以在 TabControl 中找到所有 "textBlock" 控件,如下所示:
tabControl.Descendants<TextBlock>().Where(d => d.Name=="textBlock");
然后您将可以控制 TextBlock 属性
对于任何试图完成同类任务的人,有一种方法可以参考父资源并"query"它们以获取信息。
我没有在 TabItem
上放置触发器来更改字体的颜色,而是在引用 TabItem
状态的 TextBlock
上放置触发器。
您最终会使用 DataTrigger
并使用 RelativeSource
设置绑定它。在我的例子中,我用 {RelativeSource AncestorType={x:Type TabItem}}}
TabItem
这是我应用到 TextBlock
控件的 XAML 样式:
<Style x:Key="HeaderTextStyle" TargetType="{x:Type TextBlock}">
<Setter Property="TextWrapping" Value="NoWrap"/>
<Setter Property="TextTrimming" Value="None"/>
<Setter Property="Foreground" Value="{StaticResource HeaderTextColor_NotSelected}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type TabItem}}}" Value="true">
<Setter Property="Foreground" Value="{StaticResource HeaderTextColor}"/>
</DataTrigger>
</Style.Triggers>
</Style>