Making animations work for disabled controls

Problem -

I was using an animation to change the Background and Foreground color of a control, whenever a value attached to it changes; it was working fine except for controls which are disabled. One possible reason for this behavior is that a Rectangle or a Border is used in controls style when control is disabled, which overlays the Background panel, so even though the Background and Foreground color’s change they are not visible.

Here is the animation used

<Storyboard 
    x:Key="Anim" 
    AutoReverse="True" 
    Duration="500" 
    FillBehavior="Stop"> 
    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background"> 
        <DiscreteObjectKeyFrame KeyTime="0:0:0.002"> 
            <DiscreteObjectKeyFrame.Value> 
                <SolidColorBrush Color="Red" /> 
            </DiscreteObjectKeyFrame.Value> 
        </DiscreteObjectKeyFrame> 
    </ObjectAnimationUsingKeyFrames> 
    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground"> 
        <DiscreteObjectKeyFrame KeyTime="0:0:0.002"> 
            <DiscreteObjectKeyFrame.Value> 
                <SolidColorBrush Color="White" /> 
            </DiscreteObjectKeyFrame.Value> 
        </DiscreteObjectKeyFrame> 
    </ObjectAnimationUsingKeyFrames> 
</Storyboard> 

I am setting the target for this animation at run time like this -

Storyboard anim = this.FindResource("Anim") as Storyboard;
if (anim != null)
{
    anim.SetValue(Storyboard.TargetProperty, animationTarget);
}

and whenever value changes I do

_animation.Begin();

Note that animationTarget control can be of different type e.g. TextBox, DropDown, Calendar etc. and can be Enabled or Disabled based on ViewModel properties.

Solution -

Using BooleanAnimationUsingKeyFrames: So after trying a lot of things finally I came across BooleanAnimationUsingKeyFrames, it Animates the value of a property that takes a Boolean along a set of KeyFrames over a specified Duration

Here is the modified Storyboard -

<Storyboard 
    x:Key="Anim" 
    AutoReverse="True" 
    Duration="500" 
    FillBehavior="Stop"> 
    <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsEnabled">
        <DiscreteBooleanKeyFrame
             KeyTime="0:0:0.002"
             Value="True" />
    </BooleanAnimationUsingKeyFrames>
    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background"> 
        <DiscreteObjectKeyFrame KeyTime="0:0:0.002"> 
            <DiscreteObjectKeyFrame.Value> 
                <SolidColorBrush Color="Red" /> 
            </DiscreteObjectKeyFrame.Value> 
        </DiscreteObjectKeyFrame> 
    </ObjectAnimationUsingKeyFrames> 
    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground"> 
        <DiscreteObjectKeyFrame KeyTime="0:0:0.002"> 
            <DiscreteObjectKeyFrame.Value> 
                <SolidColorBrush Color="White" /> 
            </DiscreteObjectKeyFrame.Value> 
        </DiscreteObjectKeyFrame> 
    </ObjectAnimationUsingKeyFrames> 
</Storyboard> 

So when this animation is applied control becomes enabled for short time interval, animation runs and the control is again disabled.

The only downside of this approach is that for some controls there is a flickering when animation is applied e.g. calendar control, calendar button becomes enabled when animation is applied and gets hidden after that.

1 Comment

Add a Comment

As it will appear on the website

Not displayed

Your website