WPF:ContentPresenter 根据样式所在位置意外更改前景

发布于 2024-09-04 05:51:57 字数 8276 浏览 12 评论 0原文

我遇到了 ContentPresenter 根据样式是否位于窗口中而表现异常的问题。资源或资源字典中。具体来说,我将默认 TextBlock 的前景设置为黑色,然后将默认按钮样式中的前景值设置为白色。

如果页面上存在这样的样式,它们可以正常工作:

<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,按钮的前景将切换为黑色。

更新了 MainWindow:

<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:

<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>

任何帮助将不胜感激:)

I'm having an issue with the ContentPresenter behaving unexpectedly based on whether the styles are located in the Window. Resources or in a ResourceDictionary. Specifically, I'm setting the Foreground of the default TextBlock to Black, then setting the Foreground value in my default button style to White.

If the styles exists on the page like this, they work fine:

<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>

But if I move those same styles over to a ResourceDictionary, the Foreground of the button switches to black.

Updated MainWindow:

<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:

<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>

And my App.xaml because someone will ask for it:

<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>

Any help would be greatly appreciated :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

腹黑女流氓 2024-09-11 05:51:57

才发现我从来没有回答过这个问题。简而言之,您应该始终使用标签而不是文本块,因为文本块实际上并不是控件。

Just realized I never answered this. The short version is you should always use labels rather than textblocks, because textblocks aren't actually controls.

飞烟轻若梦 2024-09-11 05:51:57

我们是说它在设计时或运行时表现得很奇怪吗?我之前在 Visual Studio 设计器方面遇到过问题...尤其是 App.Xaml 在我执行运行时之前无法工作。

Are we talking that it behaves oddly design-time or run-time. I've had issues with the Visual Studio designer before... Especially with the App.Xaml not working before I do run-time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文