Starting Point
In my earlier post, the HiliteTextBox, I created a simple WPF UserControl which is hosted in an ElementHost in a Windows Form. If the user tries to continue without entering text in the TextBox, a bright colored Border would appear around it and stay there until the user does enter something.

If we are going to go to the trouble of harnessing WPF's graphics power, we may as well go a step further and add some animation to the control. One simple thing we can do is to animate the Border Thickness.
This is the XAML for the UserControl I created previously. The only thing I have changed is the class name. It was originally HiliteTextBox, but for this version it will be named AnimatedTextBox :
<UserControl x:Class="AnimatedTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="300" Height="300">
<UserControl.Resources>
<LinearGradientBrush x:Key="BrightGradient" EndPoint="0.056,0.993" StartPoint="0.634,0.342" SpreadMethod="Repeat">
<GradientStop Color="#FFB50D0D"/>
<GradientStop Color="#FFE80C2C" Offset="1"/>
<GradientStop Color="#FFF4DF5A" Offset="0.17399999499320984"/>
<GradientStop Color="#FFCA0C1F" Offset="0.357"/>
<GradientStop Color="#FFDCD762" Offset="0.522"/>
<GradientStop Color="#FFB70D36" Offset="0.716"/>
<GradientStop Color="#FFDDEE49" Offset="0.823"/>
</LinearGradientBrush>
</UserControl.Resources>
<Border x:Name="GradBorder"
BorderBrush="LightGray"
BorderThickness="5"
CornerRadius="4,4,4,4">
<TextBox x:Name="InputTextBox"
TextWrapping="Wrap"
TextChanged="InputTextBox_TextChanged" >
</TextBox>
</Border>
</UserControl>
And this is the code-behind in the UserControl:
Private Sub InputTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.TextChangedEventArgs)
HighlightEmpty()
End Sub
Public Sub HighlightEmpty()
If InputTextBox.Text.Length > 0 Then
GradBorder.BorderBrush = New SolidColorBrush(Colors.Black)
GradBorder.BorderThickness = New Thickness(1)
Else
GradBorder.BorderBrush = FindResource("BrightGradient")
GradBorder.BorderThickness = New Thickness(4)
End If
End Sub
Public Function IsTBEmpty() As Boolean
If InputTextBox.Text.Length = 0 Then
Return True
Else
Return False
End If
End Function
Creating the Animation in Code
Generally, you will find XAML to be the best tool for creating animations - and if they are quite complex then Expression Blend is your best bet. However, you can create a simple animation in the UserControl using code. The following code-behind in the UserControl will cause the Border to change in size over a short period of time:
Public Sub ChangeSize()
Dim ThickAnim As New ThicknessAnimation
With ThickAnim
.To = New Thickness(14)
.AutoReverse = True
.Duration = New Duration(TimeSpan.FromSeconds(0.6))
End With
Me.GradBorder.BeginAnimation(Border.BorderThicknessProperty, ThickAnim)
End Sub
Even if you have no experience of WPF, most of the above code is relatively easy to follow.
ThicknessAnimation is a class that 'does what it says on the tin', as we say here in the UK - it does exactly what you would expect. It animates the Thickness Property of a target element.
To sets the value of the Thickness that has to be reached by the conclusion of the animation.
AutoReverse ensures that the Thickness returns to its starting value by the end of the animation sequence.
Duration assigns the length of time for which the animation will run. Note that in the case of this AutoReversed animation both the increase (The To value) and the decrease (AutoReverse to the start value) in size are completed within the allowed Duration.
The BeginAnimation Method takes parameters of a kind that might be unfamiliar. It takes the WPF DependencyProperty for the Border class as the first argument and it takes the ThicknessAnimation instance as the second argument. The correct element is animated, of course, because the BeginAnimation method is applied to GradBorder, the Border instance we are dealing with.
Me.GradBorder.BeginAnimation(Border.BorderThicknessProperty, ThickAnim)
To get the animation to run, we can incorporate it into the code we used previously that tests if the TextBox is empty. This code is in the Windows Form on which we placed an ElementHost to house the WPF UserControl :
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If AnimatedTextBox1.IsTBEmpty = True Then
' Change to bright gradient border
AnimatedTextBox1.HighlightEmpty()
' Animate
AnimatedTextBox1.ChangeSize()
' Return focus
Me.ElementHost1.Focus()
Else
MessageBox.Show("You are clear to continue")
End If
End Sub
If you try this code and run the project, click the Continue Button with no text in the TextBox, you will see that the Gradient Border appears and then the Border size is animated.
One thing you may have noticed is that the target in the Button Click event is an object named AnimatedTextBox1. If you scour through the small amount of code I have written so far, you won't find where I created this object. The reason being that I didn't. When you use the Smart Tag in the ElementHost and select the content, it will automatically create an instance for you and name it.
In the next part, I will create a different animation using what on the face of it seems to be a very complex block of XAML. When we take a closer look, you will see that it is not as complicated as it first appears.