You can do what your looking for without having to use a ContentControl
and by just using the VisualStateManager
I can of course change the text color by editing the style, but this is not useful as it is within the states I'm interesting in editing.
So say for example the state to apply a new Foreground
color to the text of your Button
is MouseOver
,
- Firstly Blend does not create a
Brush
resource forButton.MouseOver.Foreground
when editing aButton
template.
so let's create one. (Just add the following line along with the other brush resources)
<SolidColorBrush x:Key="Button.MouseOver.Foreground" Color="Tomato" />
- Now we can apply a
Storyboard
to theTextElement.Foreground
of thecontentPresenter
.
so your VSM will look like:
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="contentPresenter"
Storyboard.TargetProperty="(TextElement.Foreground)">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="{Binding Source={StaticResource Button.MouseOver.Foreground}, Path=Color}" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed"/>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
and that's it.
Do note what we're doing here would be fine only when the Content
of the Button
is just text, but since that's what your usage is as mentioned in your question, you should be fine.
Sidenote:
You can do the exact same thing by just switching the ContentPresenter
to a TextBlock
in the ControlTemplate
.
If you need the Foreground
to be available for any Content
of the Button
, then yeh just switch the ContentPresenter
to a ContentControl
and you can still your VSM Storyboard's in a very similar way.
Update:
To switch the ContentPresenter
to a ContentControl
, in your ControlTemplate
just switch the actual element with the new one.
<ControlTemplate TargetType="{x:Type Button}">
...
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True"/>
...
</ControlTemplate>
to:
<ControlTemplate TargetType="{x:Type Button}">
...
<ContentControl x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Content="{TemplateBinding Content}"/>
...
</ControlTemplate>
you would have to update their properties accordingly like for eg ContentControl
does not support RecognizesAccessKeys
and it also needs Content="{TemplateBinding Content}"
set on it to actually show the content. With a ContentPresenter
the Content
property is set implicitly.