WPF: ContentPresenter changing Foreground unexpectedly depending on where styles are located

Posted by VLTII on Stack Overflow See other posts from Stack Overflow or by VLTII
Published on 2010-06-03T13:18:14Z Indexed on 2010/06/03 21:24 UTC
Read the original article Hit count: 774

Filed under:
|
|
|

Hi,

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

© Stack Overflow or respective owner

Related posts about wpf

Related posts about xaml