我想将前景(文本)颜色设置为我的所有元素你会认为这很容易,但它不是......
<Window Foreground="Red">
<Label Content="Test"/>
<Label Content="Test"/>
<CheckBox Content="Checkbox"/>
</Window>
Run Code Online (Sandbox Code Playgroud)
这没有任何影响......我可以让它工作的唯一方法是,如果我专门为每个元素设置Foreground属性.如果你有数百个元素等,这会很烦人.
也许你知道一种方式?
Pav*_*kov 27
这是因为这样的控件Label和CheckBox覆盖Foreground其样式中的属性.
下面是一个典型的元素逻辑树的示例,它显示了在层上指定的值如何Window沿树向下移动:
Window (Red [Local])
-> Grid (Red [Inherited])
-> ListBox (Red [Inherited])
-> ListBoxItem (Red [Inherited])
-> StackPanel (Red [Inherited])
-> Label (Black [Style])
-> TextBlock (Black [Inherited])
-> TextBlock (Red [Inherited])
Run Code Online (Sandbox Code Playgroud)
在方括号中,显示值的来源.
正如您所看到的,继承会Label自行中断,因为它具有Foreground以其默认样式设置的属性:
<Style x:Key="{x:Type Label}"
TargetType="{x:Type Label}">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
...
</Style>
Run Code Online (Sandbox Code Playgroud)
作为解决方法,我们可以使用以下技巧.Label在应用程序中定义此类控件(如)的默认样式(在App.xaml或Windowinself中).并且在该默认样式中覆盖该Foreground属性以设置相对源绑定到仍具有所需值的控件的最近祖先:
<Style TargetType="{x:Type Label}">
<Setter Property="Foreground"
Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}, Path=(TextElement.Foreground)}"/>
</Style>
<Style TargetType="{x:Type CheckBox}">
<Setter Property="Foreground"
Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}, Path=(TextElement.Foreground)}"/>
</Style>
Run Code Online (Sandbox Code Playgroud)
之后,我们的树将如下所示:
Window (Red [Local])
-> Grid (Red [Inherited])
-> ListBox (Red [Inherited])
-> ListBoxItem (Red [Inherited])
-> StackPanel (Red [Inherited])
-> Label (Red [Binding to StackPanel.(TextElement.Foreground)])
-> TextBlock (Red [Inherited])
-> TextBlock (Red [Inherited])
Run Code Online (Sandbox Code Playgroud)
如您所见,我们的绑定恢复了继承.
需要为每个Foreground在其样式中覆盖属性的元素定义此类样式.正如@Duane建议的那样,为了不在每种样式中复制绑定,BasedOn可以使用该功能:
<Style x:Key="ForegroundInheritanceFixStyle"
TargetType="Control">
<Setter Property="Foreground"
Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}, Path=(TextElement.Foreground)}"/>
</Style>
<Style TargetType="{x:Type Label}"
BasedOn="{StaticResource ForegroundInheritanceFixStyle}">
</Style>
<Style TargetType="{x:Type CheckBox}"
BasedOn="{StaticResource ForegroundInheritanceFixStyle}">
</Style>
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.
遗憾的是,样式在WPF中的工作方式不能在父类上创建通用样式,并且它适用于子类控件.
您可以做的一件事是创建一个基本样式,该基本样式使用您要设置的属性(如ContentControl)定位基本类型,然后为每个基于该样式的控件创建特定样式.这是一个例子:
<Window>
<Window.Resources>
<Style x:Key="BaseContentControlStyle" TargetType="{x:Type ContentControl}">
<Setter Property="Foreground" Value="Red" />
</Style>
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource BaseContentControlStyle}" />
<Style TargetType="{x:Type CheckBox}" BasedOn="{StaticResource BaseContentControlStyle}" />
</Window.Resources>
<StackPanel>
<Label Content="Test"/>
<Label Content="Test"/>
<CheckBox Content="Checkbox"/>
</StackPanel>
</Window>
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.
编辑:
您可以使用下面的Pavlo方法来恢复继承,并使其更容易使用,如下所示:
<Window.Resources>
<Style x:Key="BaseContentControlStyle" TargetType="{x:Type Control}">
<Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}, Path=(TextElement.Foreground)}"/>
</Style>
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource BaseContentControlStyle}" />
<Style TargetType="{x:Type CheckBox}" BasedOn="{StaticResource BaseContentControlStyle}" />
</Window.Resources>
Run Code Online (Sandbox Code Playgroud)
至少那时你不必在任何地方复制相同的setter代码(BTW,我认为TextBlock默认继承;没有覆盖的默认样式).
| 归档时间: |
|
| 查看次数: |
10289 次 |
| 最近记录: |