WPF:ContentPresenter 根据样式的位置意外更改前景
Posted
技术标签:
【中文标题】WPF:ContentPresenter 根据样式的位置意外更改前景【英文标题】:WPF: ContentPresenter changing Foreground unexpectedly depending on where styles are located 【发布时间】:2011-02-27 07:40:31 【问题描述】:我遇到了 ContentPresenter 基于样式是否位于窗口中的异常行为的问题。资源或在 ResourceDictionary 中。具体来说,我将默认 TextBlock 的 Foreground 设置为 Black,然后将我的默认按钮样式中的 Foreground 值设置为 White。
如果页面上存在这样的样式,它们可以正常工作:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
x:Class="TestBed.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Window.Resources>
<Style TargetType="x:Type TextBlock">
<Setter Property="Foreground" Value="Black" />
</Style>
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Stroke="Black" StrokeDashArray="1 2" StrokeThickness="1" Margin="2" SnapsToDevicePixels="true"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#F3F3F3" Offset="0"/>
<GradientStop Color="#EBEBEB" Offset="0.5"/>
<GradientStop Color="#DDDDDD" Offset="0.5"/>
<GradientStop Color="#CDCDCD" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF707070"/>
<Style TargetType="x:Type Button">
<Setter Property="FocusVisualStyle" Value="StaticResource ButtonFocusVisual"/>
<Setter Property="Background" Value="StaticResource ButtonNormalBackground"/>
<Setter Property="BorderBrush" Value="StaticResource ButtonNormalBorder"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="x:Type Button">
<Microsoft_Windows_Themes:ButtonChrome x:Name="Chrome" SnapsToDevicePixels="true" Background="TemplateBinding Background" BorderBrush="TemplateBinding BorderBrush" RenderDefaulted="TemplateBinding IsDefaulted" RenderMouseOver="TemplateBinding IsMouseOver" RenderPressed="TemplateBinding IsPressed">
<ContentPresenter HorizontalAlignment="TemplateBinding HorizontalContentAlignment" Margin="TemplateBinding Padding" VerticalAlignment="TemplateBinding VerticalContentAlignment" SnapsToDevicePixels="TemplateBinding SnapsToDevicePixels" RecognizesAccessKey="True"/>
</Microsoft_Windows_Themes:ButtonChrome>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="RenderDefaulted" TargetName="Chrome" Value="true"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="true">
<Setter Property="RenderPressed" TargetName="Chrome" Value="true"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel x:Name="LayoutRoot">
<Button Content="Button" />
</StackPanel>
</Window>
但是,如果我将这些相同的样式移至 ResourceDictionary,按钮的前景将变为黑色。
更新主窗口:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
x:Class="TestBed.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<StackPanel x:Name="LayoutRoot">
<Button Content="Button" />
</StackPanel>
</Window>
资源字典:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Style TargetType="x:Type TextBlock">
<Setter Property="Foreground" Value="Black" />
</Style>
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Stroke="Black" StrokeDashArray="1 2" StrokeThickness="1" Margin="2" SnapsToDevicePixels="true"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#F3F3F3" Offset="0"/>
<GradientStop Color="#EBEBEB" Offset="0.5"/>
<GradientStop Color="#DDDDDD" Offset="0.5"/>
<GradientStop Color="#CDCDCD" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF707070"/>
<Style TargetType="x:Type Button">
<Setter Property="FocusVisualStyle" Value="StaticResource ButtonFocusVisual"/>
<Setter Property="Background" Value="StaticResource ButtonNormalBackground"/>
<Setter Property="BorderBrush" Value="StaticResource ButtonNormalBorder"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="x:Type Button">
<Microsoft_Windows_Themes:ButtonChrome x:Name="Chrome" SnapsToDevicePixels="true" Background="TemplateBinding Background" BorderBrush="TemplateBinding BorderBrush" RenderDefaulted="TemplateBinding IsDefaulted" RenderMouseOver="TemplateBinding IsMouseOver" RenderPressed="TemplateBinding IsPressed">
<ContentPresenter HorizontalAlignment="TemplateBinding HorizontalContentAlignment" Margin="TemplateBinding Padding" VerticalAlignment="TemplateBinding VerticalContentAlignment" SnapsToDevicePixels="TemplateBinding SnapsToDevicePixels" RecognizesAccessKey="True"/>
</Microsoft_Windows_Themes:ButtonChrome>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="RenderDefaulted" TargetName="Chrome" Value="true"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="true">
<Setter Property="RenderPressed" TargetName="Chrome" Value="true"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
还有我的 App.xaml,因为有人会要求它:
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="TestBed.App"
StartupUri="MainWindow.xaml">
<Application.Resources>
<!-- Resources scoped at the Application level should be defined here. -->
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ResourceDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
任何帮助将不胜感激:)
【问题讨论】:
【参考方案1】:刚刚意识到我从来没有回答过这个问题。简短的版本是您应该始终使用标签而不是文本块,因为文本块实际上并不是控件。
【讨论】:
感谢您的信息,我一直在努力更改自定义 dataGrid 的前景色【参考方案2】:我们是在说它在设计时或运行时表现得奇怪吗?我之前在使用 Visual Studio 设计器时遇到过问题……尤其是 App.Xaml 在我运行之前无法正常工作。
【讨论】:
对不起,我可能对这个问题不够清楚 - 这是在运行时。如果样式在 Window 上,则按钮的文本颜色按预期工作并且为白色。一旦我将它移出窗口并进入 ResourceDictionary,文本就会变成黑色。以上是关于WPF:ContentPresenter 根据样式的位置意外更改前景的主要内容,如果未能解决你的问题,请参考以下文章
WPF WindowChrome ContentPresenter 不显示内容