Silverlight 3.0 Behaviors – Part 2

Today I am going to explore Silverlight three behaviors a little more.  In this post I am going to look at different events that can trigger an action in a behavior.  Essentially, we can specify any event on a target element to invoke a behavior. 

Again, we are going to use TargetedTriggerAction base class. This time however we are going to enable this behavior to be able to be used on a larger suite of targets.  We are going to use UIElement as the target type: TargetedTriggerAction<UIElement>.  We are only going to override one method – InvokeAction.  Here is what the class looks like:

    public class MakeLargerSmallerAction : TargetedTriggerAction<UIElement>

    {

        protected override void Invoke(object parameter)

        {

            StoryBoardHelper.PlayControlAnimation(Target, Percent);

        }

Here are a couple of things I need to explain. 

  1. This behavior is going to perform one function – change dimensions (increase or decrease the size) of the target control base on an event.  We are going to add a property that would allow our behavior to specify the factor by which the target’s size needs to increase or decrease.
  2. We are going to use animations to perform this function.  We will build animations in code.
  3. We will invoke animations based on event specified in XAML.

Here is full source code for behavior class:

using System;

using System.Windows.Interactivity;

using System.Windows;

 

namespace Behaviors

{

    public class MakeLargerSmallerAction : TargetedTriggerAction<UIElement>

    {

        protected override void Invoke(object parameter)

        {

            StoryBoardHelper.PlayControlAnimation(Target, Percent);

        }

 

        public double Percent

        {

            get { return (double)GetValue(PercentProperty); }

            set { SetValue(PercentProperty, value); }

        }

 

        public static readonly DependencyProperty PercentProperty =

            DependencyProperty.Register("Percent", typeof(double), typeof(MakeLargerSmallerAction), new PropertyMetadata((double)1));

 

 

    }

}

Here is source code for animation controller:

using System;

using System.Windows;

using System.Windows.Media;

using System.Windows.Media.Animation;

 

namespace Behaviors

{

    public static class StoryBoardHelper

    {

        public static void PlayControlAnimation(UIElement controlToAnimate, double factor)

        {

            Storyboard story = new Storyboard();

 

            //stretch horizontally

            DoubleAnimationUsingKeyFrames scaleXAnimation = new DoubleAnimationUsingKeyFrames();

            scaleXAnimation.BeginTime = TimeSpan.FromMilliseconds(0);

            scaleXAnimation.KeyFrames.Add(CreateFrame(factor, 100));

            Storyboard.SetTarget(scaleXAnimation, controlToAnimate);

            Storyboard.SetTargetProperty(scaleXAnimation, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"));

            story.Children.Add(scaleXAnimation);

 

            //stretch vertically

            DoubleAnimationUsingKeyFrames scaleYAnimation = new DoubleAnimationUsingKeyFrames();

            scaleYAnimation.BeginTime = TimeSpan.FromMilliseconds(0);

            scaleYAnimation.KeyFrames.Add(CreateFrame(factor, 100));

            Storyboard.SetTarget(scaleYAnimation, controlToAnimate);

            Storyboard.SetTargetProperty(scaleYAnimation, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"));

            story.Children.Add(scaleYAnimation);

 

            if (!(controlToAnimate.RenderTransform is TransformGroup))

            {

                TransformGroup group = new TransformGroup();

                ScaleTransform transform = new ScaleTransform();

                transform.ScaleX = 1;

                transform.ScaleY = 1;

                group.Children.Add(transform);

                controlToAnimate.RenderTransformOrigin = new Point(0.5, 0.5);

                controlToAnimate.RenderTransform = group;

            }

            story.Begin();

 

 

        }

 

        private static SplineDoubleKeyFrame CreateFrame(double value, double duration)

        {

            SplineDoubleKeyFrame frame = new SplineDoubleKeyFrame();

            frame.Value = value;

            frame.KeyTime = TimeSpan.FromMilliseconds(duration);

            return frame;

        }

    }

}

Here is how we are setting up behaviors in XAML:

        <TextBox x:Name="FirstBox" TextWrapping="Wrap" Margin="20,0,0,7" d:LayoutOverrides="Height">

            <i:Interaction.Triggers>

                <i:EventTrigger>

                    <Behaviors:SelectOnFocusAction/>

                </i:EventTrigger>

                <i:EventTrigger EventName="GotFocus">

                    <Behaviors:MakeLargerSmallerAction Percent="1.2"/>

                </i:EventTrigger>

                <i:EventTrigger EventName="LostFocus">

                    <Behaviors:MakeLargerSmallerAction Percent="1"/>

                </i:EventTrigger>

            </i:Interaction.Triggers>

        </TextBox>

In the XAML above we are setting up three different behaviors.  First one I covered in previous post.  The second trigger increases the size of the control by factor of 1.2 – 20 %.  This action is executed when GotFocus event fires.  The last trigger changes the control’s size back to original size.

You can download full sample project here.

Leave a Reply

Your email address will not be published. Required fields are marked *