开发具有区域的应用程序,每个区域具有不同的前景色。
问题的一般框架如下所示:
<Window Style={StaticResource GrayForeground}>
<UniformGrid Rows="1">
<Grid x:Name="defaultColor">
<!-- Text elements here -->
</Grid>
<Grid x:Name="emphasisColor"
TextElement.Foreground="Red">
<!-- Text elements here -->
</Grid>
</UniformGrid>
</Window>
其中
GrayForeground
风格是:
<Style x:Key="GrayForeground"
TargetType="{x:Type Window}">
<Setter Property="TextElement.Foreground"
Value="Gray" />
</Style>
这对于
TextBlock
非常有用 - 那些位于 defaultColor
网格内的前景是灰色的,而那些位于 emphasisColor
网格中的前景是红色的。
现在我需要定义一个
Label
以允许我在设置 TextBlock
的文本之前进行一些格式化,因此我为标签创建了一个样式:
<Style x:Key="LabelForNumbers"
TargetType="{x:Type Label}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<!-- MultiBinding with converter to set correct formatting -->
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
问题:
Label
的所有实例都有黑色前景。Label
的默认样式将前景设置为黑色。
问题:
有没有办法取消设置前景的值,以便
Label
将继续传播/继承 TextElement.Foreground
属性?
我能想到的唯一解决方案是将这个设置器添加到标签的样式中:
<Setter Property="Foreground">
<Setter.Value>
<PriorityBinding FallbackValue="Gray">
<Binding Path="(TextElement.Foreground)"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type FrameworkElement}}" />
<Binding Path="Foreground"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type FrameworkElement}}" />
</PriorityBinding>
</Setter.Value>
</Setter>
它似乎可以工作,但感觉“hacky”并且不像 WPF。
当你说(强调我的)时我很担心:
该 Label 将继续传播/继承 TextElement.Foreground 属性[...]
使用我能召集的最小设置,我一开始就没有看到
Label
这样做。我的理解是,标签的内容呈现者并不像文本块那样位于继承链中。
<!--Parent with explicit blue foreground-->
<Window
x:Name="Top"
x:Class="style_inheritance.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:style_inheritance"
mc:Ignorable="d"
Title="MainWindow" Height="250" Width="400"
WindowStartupLocation="CenterScreen"
TextElement.Foreground="Blue">
<!--Testing suggests that property does not propagate to content presenter in Label-->
<Label
Content="Still black"/>
</Window>
因此,您对样式中相对设置器的想法可能最适合您的要求或只需切入正题并在此处动态绑定到父样式:
<Window
x:Name="Top"
x:Class="style_inheritance.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:style_inheritance"
mc:Ignorable="d"
Title="MainWindow" Height="250" Width="400"
WindowStartupLocation="CenterScreen"
TextElement.Foreground="Blue">
<Label
Content="Now tracks"
Foreground="{Binding ElementName=Top, Path=(TextElement.Foreground)}" />
</Window>