MattC
MattC

Reputation: 4004

Animation causes button to become invisible

I've been trying to get a user control to animate when IsEnabled changes.

Loosely based on this post Button Blinking on DataTrigger

However, when I include the ControlTemplate style the button is invisible. :)

<UserControl x:Class="View.UserControls.MainButton"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         mc:Ignorable="d" 
         d:DesignHeight="40" d:DesignWidth="300">
<UserControl.Resources>
    <Style TargetType="{x:Type Button}">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="Cursor" Value="Hand" />
        <Setter Property="MinHeight" Value="24" />
        <Setter Property="Background">
            <Setter.Value>
                <SolidColorBrush Color="Transparent"/>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled" Value="True">
                            <Trigger.EnterActions>
                                <BeginStoryboard Name="StartBlinking">
                                    <Storyboard>
                                        <ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)" To="Orange" Duration="00:00:00.4" RepeatBehavior="3" AutoReverse="True"/>
                                    </Storyboard>
                                </BeginStoryboard>
                            </Trigger.EnterActions>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="False">
                            <Trigger.ExitActions>
                                <RemoveStoryboard BeginStoryboardName="StartBlinking"/>
                            </Trigger.ExitActions>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style TargetType="{x:Type StackPanel}">
        <Setter Property="Orientation" Value="Horizontal" />
    </Style>
    <Style TargetType="{x:Type Image}">
        <!--<Setter Property="Height" Value="32" />
        <Setter Property="Width" Value="32" />-->
        <Setter Property="Stretch" Value="Uniform" />
    </Style>
    <Style TargetType="{x:Type TextBlock}">
        <Setter Property="VerticalAlignment" Value="Center" />
        <Setter Property="Margin" Value="5 0 0 0" />
    </Style>
</UserControl.Resources>
<Button Width="{Binding Width, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
        Command="{Binding Command, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" 
        ToolTip="{Binding ToolTip, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}">
    <StackPanel>
        <Image Source="{Binding ButtonImageSource, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />
        <TextBlock Text="{Binding ButtonText, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />
    </StackPanel>
</Button>

Upvotes: 0

Views: 46

Answers (2)

The template defines the visual appearance of the control. Anything not put there by the template isn't there. Your template puts no visual elements in the control. Therefore, there is nothing visual to be seen.

If you're replacing the template, at absolute minimum, you'll have to give it a ContentPresenter inside a Border that will show the blinking Background brush color:

<ControlTemplate TargetType="{x:Type Button}">
    <Border Background="{TemplateBinding Background}">
        <ContentPresenter
            />
    </Border>
    <ControlTemplate.Triggers>
        <Trigger Property="IsEnabled" Value="True">
            <Trigger.EnterActions>
                <BeginStoryboard Name="StartBlinking">
                    <Storyboard>
                        <ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)" To="Orange" Duration="00:00:00.4" RepeatBehavior="3" AutoReverse="True"/>
                    </Storyboard>
                </BeginStoryboard>
            </Trigger.EnterActions>
        </Trigger>
        <Trigger Property="IsEnabled" Value="False">
            <Trigger.ExitActions>
                <RemoveStoryboard BeginStoryboardName="StartBlinking"/>
            </Trigger.ExitActions>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

But if you're happy with the standard Button template, use mm8's approach instead, which leaves that in place. Rewriting standard templates usually turns out to be a lot more effort than it's worth, if you can find another way to do what you need to.

Upvotes: 1

mm8
mm8

Reputation: 169200

Move the triggers to the Style and avoid overriding the ControlTemplate if you want the Button to still look like a Button:

<Style TargetType="{x:Type Button}">
    <Setter Property="HorizontalAlignment" Value="Center" />
    <Setter Property="Cursor" Value="Hand" />
    <Setter Property="MinHeight" Value="24" />
    <Setter Property="Background">
        <Setter.Value>
            <SolidColorBrush Color="Transparent"/>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsEnabled" Value="True">
            <Trigger.EnterActions>
                <BeginStoryboard Name="StartBlinking">
                    <Storyboard>
                        <ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)" To="Orange" Duration="00:00:00.4" RepeatBehavior="3" AutoReverse="True"/>
                    </Storyboard>
                </BeginStoryboard>
            </Trigger.EnterActions>
        </Trigger>
        <Trigger Property="IsEnabled" Value="False">
            <Trigger.ExitActions>
                <RemoveStoryboard BeginStoryboardName="StartBlinking"/>
            </Trigger.ExitActions>
        </Trigger>
    </Style.Triggers>
</Style>

Upvotes: 1

Related Questions