wpfrendertransform

Animating two UserControls on the same ContentControl at the same time


I've these Load and Unload animations in App.xaml:

<Storyboard x:Key="Unload">
    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
        <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
        <EasingDoubleKeyFrame KeyTime="0:0:3" Value="-800"/>
    </DoubleAnimationUsingKeyFrames>
</Storyboard>

<Storyboard x:Key="Load">
    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
        <EasingDoubleKeyFrame KeyTime="0" Value="800"/>
        <EasingDoubleKeyFrame KeyTime="0:0:3" Value="0"/>
    </DoubleAnimationUsingKeyFrames>
</Storyboard>

In my code I'm calling those on Button Clicks like these:

sb1 = FindResource("Unload") as Storyboard;
sb2 = FindResource("Load") as Storyboard;

void Button_Click(object sender, RoutedEventArgs e)
{
    uc1.RenderTransform = GetTG();
    uc2.RenderTransform = GetTG();

    sb1.Begin(uc2);
    sb2.Begin(uc1);

    content.Content = uc1;
}

//and 

void Button_Click_1(object sender, RoutedEventArgs e)
{
    uc2.RenderTransform = GetTG();
    uc1.RenderTransform = GetTG();

    sb2.Begin(uc2);
    sb1.Begin(uc1);

    content.Content = uc2;
}

GetTG returns a TransformGroup

TransformGroup GetTG()
{
    var tg = new TransformGroup();
    tg.Children.Add(new ScaleTransform());
    tg.Children.Add(new SkewTransform());
    tg.Children.Add(new RotateTransform());
    tg.Children.Add(new TranslateTransform());
    return tg;
}

with these only the Load animation works. How to make both work at the same time?


Solution

  • Apply the animation to the ContentControl. This should slide out the current Content/UserControl to the left and slide in the new Content/UserControl from the right:

    void Button_Click(object sender, RoutedEventArgs e)
    {
        UnLoadAndLoad(uc1);
    }
    
    void Button_Click_1(object sender, RoutedEventArgs e)
    {
        UnLoadAndLoad(uc2);
    }
    
    void UnLoadAndLoad(object ucToBeLoaded)
    {
        if (content.Content != ucToBeLoaded)
        {
            content.RenderTransform = GetTG();
    
            EventHandler completed = null;
            completed = (ss, ee) =>
            {
                sb1.Completed -= completed;
                content.Content = ucToBeLoaded;
                //load
                sb2.Begin(content);
            };
            sb1.Completed += completed;
            //unload
    
            if (content.Content != null)
                sb1.Begin(content);
            else
                completed(this, EventArgs.Empty);
        }
    }