我的问题出现在.NET 3.5 SP1中的WPF中,可以描述如下:
我的默认Style
命中了我的UI中的所有TextBlock
元素。这就是它的样子:
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
<Setter Property="Foreground" Value="Red"/>
</Style>
这适用于所有TextBlock
。除此之外,我有一个Button
样式,包括ControlTemplate
,看起来像这样(缩短):
<Style x:Key="MyButtonStyle" TargetType="{x:Type Button}" BasedOn="{x:Null}">
<Setter Property="Foreground" Value="Green"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Border"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
Height="24"
BorderBrush="{TemplateBinding BorderBrush}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
TextBlock.Foreground="{TemplateBinding Foreground}"/>
</Border>
<ControlTemplate.Triggers>...</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
注意TextBlock.Foreground="{TemplateBinding Foreground}"
中的行ContentPresenter
。这应该将按钮文本设置为绿色,实际上它在Visual Studio的设计器视图中。但是当我编译并运行程序时,按钮文本为红色,文本颜色由默认的TextBlock
样式设置。我用Snoop验证了这一点。
如何防止默认TextBlock
样式覆盖TextBlock.Foreground
值?在这种情况下,OverridesDefaultStyle
的{{1}}属性无效。
有什么想法吗?
答案 0 :(得分:11)
请参阅this link
上的答案5这发生的原因是因为 ContentPresenter创建一个TextBlock 对于字符串内容,从那以后 它不是可视树中的TextBlock 将查找到应用程序级别 资源。如果你定义一个风格 用于应用程序的TextBlock 等级,然后它将被应用于 ContentControl中的这些TextBlock
解决方法是定义一个 DataTemplate for System.String,其中 我们可以明确使用默认值 TextBlock显示内容。您 可以将DataTemplate放在 你定义的相同词典 TextBlock风格使这一点 DataTemplate将应用于 无论ContentPresenter受到什么影响 你的风格。
尝试将此添加到ResourceDictionary
<DataTemplate DataType="{x:Type sys:String}">
<TextBlock Text="{Binding}">
<TextBlock.Resources>
<Style TargetType="{x:Type TextBlock}"/>
</TextBlock.Resources>
</TextBlock>
</DataTemplate>
答案 1 :(得分:4)
最好不要覆盖TextBlock的默认样式。到目前为止我能想到的最好的想法是为Control创建一个样式并将其应用到所有顶级窗口。
<!-- App.xaml -->
<Application.Resources>
<Style x:Key="RedStyle" TargetType="{x:Type Control}">
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
<Setter Property="Foreground" Value="Red"/>
</Style>
</Application.Resources>
<!-- MainWindow.xaml -->
<Window Style="{StaticResource RedStyle}" ...>
...
</Window>
答案 2 :(得分:0)
关于2个选项:
尝试将其添加到ResourceDictionary
<DataTemplate DataType="{x:Type sys:String}">
<TextBlock Text="{Binding}">
<TextBlock.Resources>
<Style TargetType="{x:Type TextBlock}"/>
</TextBlock.Resources>
</TextBlock>
</DataTemplate>
最好不要覆盖TextBlock的默认样式。到目前为止,我能想到的最好的主意是为Control创建一种样式并将其应用于所有顶级窗口。
我建议一种替代方法,并使用附加的Dependency属性,例如
namespace AttachedProperties
{
public static class TextBlockExtensions
{
public static bool GetUseAppThemeStyle(DependencyObject obj)
{
return (bool)obj.GetValue(UseAppThemeStyleProperty);
}
public static void SetUseAppThemeStyle(DependencyObject obj, bool value)
{
obj.SetValue(UseAppThemeStyleProperty, value);
}
// Using a DependencyProperty as the backing store for UseAppThemeStyle. This enables animation, styling, binding, etc...
public static readonly DependencyProperty UseAppThemeStyleProperty =
DependencyProperty.RegisterAttached("UseAppThemeStyle", typeof(bool), typeof(TextBlockExtensions), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.Inherits));
}
}
注意:默认情况下,您可以将其设置为true或false
然后拥有名称空间:
xmlns:attachedProperties="clr-namespace:AttachedProperties"
设置默认样式:
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource {x:Type TextBlock}}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=(attachedProperties:TextBlockExtensions.UseAppThemeStyle), RelativeSource={RelativeSource Mode=Self}}" Value="True">
<Setter Property="TextTrimming" Value="CharacterEllipsis"/>
<Setter Property="Foreground" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
然后,如果您需要使用默认值,则可以设置样式的附加属性:
<Style x:Key="blueButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="attachedProperties:TextBlockExtensions.UseAppThemeStyle" Value="False" />
<Setter Property="Foreground" Value="Blue" />
</Style>
或直接在按钮上
<Button attachedProperties:TextBlockExtensions.UseAppThemeStyle="False" Foreground="Blue">I'm blue da ba dee da ba die...</Button>