Search code examples
silverlightanimationexpression-blend

Silverlight / Expression Blend - Animate using calculated value in RenderTransform


I have a Rectangle at the top of a screen that I'm trying to animate to the bottom of the screen. So, I'm trying to move this the height of the screen minus the height of the rectangle. Since the screen height will vary depending on resolution and browser size, I'm trying to animate this the value of the ActualHeight property on the user control - 20 (the height of the rectangle).

Does anyone know of a good way to use this calculated value as the distance I want to move the rectangle? Can I use a custom expression for this, and if so, what would the expression be? I also thought about adding another property to the user control that would contain this value, but it seems unnecessary to me that I would have to do that. I'd rather simply use some math in the custom expression box if possible. Thanks for any advice.


Solution

  • If you name elements within an animation storyboard (i.e. with x:Name), you can change the values within storyboards without having to create the whole thing in code.

    Here is a full example that moves the rectangle to the bottom whenever you resize the browser:

    Animation.xaml

    <UserControl
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        x:Class="StackOvewflow2.Animation"
        d:DesignWidth="640" d:DesignHeight="480"
        SizeChanged="UserControl_SizeChanged">
        <UserControl.Resources>
            <Storyboard x:Name="Storyboard1">
                <DoubleAnimation x:Name="TargetValue" Duration="0:0:1" To="380" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="rectangle" d:IsOptimized="True"/>
            </Storyboard>
        </UserControl.Resources>
        <Grid x:Name="LayoutRoot">
            <Rectangle x:Name="rectangle" Fill="LightBlue" Height="100" Stroke="Blue" StrokeThickness="6" VerticalAlignment="Top" HorizontalAlignment="Center" Width="400" RenderTransformOrigin="0.5,0.5">
                <Rectangle.RenderTransform>
                    <CompositeTransform/>
                </Rectangle.RenderTransform>
            </Rectangle>
        </Grid>
    </UserControl>
    

    Animation.cs

    using System.Windows;
    using System.Windows.Controls;
    
    namespace StackOvewflow2
    {
        public partial class Animation : UserControl
        {
            public Animation()
            {
                InitializeComponent();
            }
    
            private void UserControl_SizeChanged(object sender, SizeChangedEventArgs e)
            {
                this.TargetValue.To = e.NewSize.Height - rectangle.Height;
                Storyboard1.Begin();
            }
        }
    }