4
votes

I have Styled textboxes that use a Control Template to set the background color depending on visual state (Mouseover, Disabled, etc). Code was taken from MS' TextBox Templates page.

What I want to do is also change the Foreground (font) colour depending on the visual state. For example, on Mouseover, I want to make the text colour stand out, and on Disabled, I want to grey it out

My xaml (I have removed VisualState tags for 'Normal' and 'Disabled' and a couple of <Border.Blah> children of Border):

<Color x:Key="EditableControlHiLightColor">Ivory</Color>
<Color x:Key="EditableControlHiLightTextColor">Pink</Color>


<Style TargetType="{x:Type TextBox}">
  <Setter Property="MinWidth" Value="100" />
  <Setter Property="MinHeight" Value="20" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type TextBoxBase}">
        <Border Name="Border"
            CornerRadius="4"
            Padding="2"
            BorderThickness="1">
          <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
              <VisualState x:Name="MouseOver" >
                <Storyboard>
                  <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(TextBox.Background).Color">
                    <EasingColorKeyFrame KeyTime="0" Value="{StaticResource EditableControlHiLightColor}" />
                  </ColorAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
            </VisualStateGroup>
          </VisualStateManager.VisualStateGroups>
          <ScrollViewer Margin="0" x:Name="PART_ContentHost" />
        </Border>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

I first tried to add a new <ColorAnimationUsingKeyFrames> inside the Storyboard tag to alter the Foreground so it looks like:

<Storyboard>
  <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(TextBox.Background).Color">
    <EasingColorKeyFrame KeyTime="0" Value="{StaticResource EditableControlHiLightColor}" />
  </ColorAnimationUsingKeyFrames>
  <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(TextBox.Foreground).Color">
    <EasingColorKeyFrame KeyTime="0" Value="{StaticResource EditableControlHiLightTextColor}" />
  </ColorAnimationUsingKeyFrames>
</Storyboard>

but that had no effect - the text colour stays the same.

I figured this was due to the <Border> at the top of the <ControlTemplate>, so I tried to set a <Foreground ... > tag as a child of ControlTemplate. Visual Studio was having none of that. (The type Foreground was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built.)

I've had a look through SO and there seems to be something to do with properties that are set by template binding that cannot be changed, but in my case it's within the template that I am trying to make the change.

So, how do I change the Foreground (font) colour of a textbox in a control template using visual states?

1

1 Answers

0
votes

It seems that we can only change ScrollViewer Foreground by changing TextBox Foreground. To do this you can use Trigger:

 <ControlTemplate.Triggers>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Foreground">
                <Setter.Value>
                    <SolidColorBrush Color="{StaticResource ControlDisabledForeground}"/>
                </Setter.Value>
            </Setter>
        </Trigger>
        <Trigger Property="IsReadOnly" Value="True">
            <Setter Property="Foreground">
                <Setter.Value>
                    <SolidColorBrush Color="{StaticResource ControlReadOnlyForeground}"/>
                </Setter.Value>
            </Setter>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

You can see full code here: https://gist.github.com/Javad-Amiry2/5897049