我用以下资源创建了一个非常简单的WPF应用程序:
<Application x:Class="StyleTest.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<FontFamily x:Key="MainFontFamily">Calibri</FontFamily>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontFamily" Value="{StaticResource MainFontFamily}" />
</Style>
<Style x:Key="HyperlinkLabel" TargetType="{x:Type Label}">
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Foreground" Value="Yellow" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</Application.Resources>
TextBlock样式没有x:Key属性。我希望此属性应用于所有的TextBlocks。
UI很简单:
<Window x:Class="StyleTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="Test 123 Test 123" Style="{StaticResource HyperlinkLabel}" />
</Grid>
</Window>
当我运行应用程序时:
- "Test 123 Test 123"(测试123测试123)显示为黄色
- 当我将鼠标光标放在文本上时,鼠标光标图标将变为一只带食指的手
- 当我把鼠标光标放在文本上时,文本会变成红色
太棒了。但如果我把第一种风格从:改成
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontFamily" Value="{StaticResource MainFontFamily}" />
</Style>
至
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontFamily" Value="{StaticResource MainFontFamily}" />
<Setter Property="Foreground" Value="Blue" />
</Style>
然后,在运行应用程序时:
- 文本显示为蓝色而非黄色。这太糟糕了
- 当我将鼠标光标放在文本上时,鼠标光标图标将变为一只带食指的手。这没关系
- 当我将鼠标光标放在文本上时,文本将保持蓝色。这太糟糕了
为什么TextBlock样式与Label样式混淆了?我觉得Label继承了TextBlock。但即使是这样,标签样式也应该被使用?
如何"强制"使用标签样式?标签样式如何覆盖文本块样式?
谢谢!
Application.Resources
中应用于非控制项(如TextBlock
)的隐式样式不尊重控制边界,并且将应用于整个应用程序,而不管存在什么其他定义。这样做可能是为了允许全局应用程序范围的样式,如字体、文本大小、颜色等。
解决此问题的两个解决方案:
-
将隐式样式更改为继承自
Control
的Label
。因为它是一个控件,所以它将尊重控件边界,而不会试图覆盖应用程序中每个文本元素的属性。 -
将样式移动到
Window.Resources
而不是Application.Resources
。这样,样式就不会被视为整个应用程序的全局样式,因此在决定如何渲染项时不会被视为此样式。
不久前我也有同样的问题,这是我对所给出的描述所能做的最好的解释。Application.Resources与Window.Resourts中的隐式样式?:)