views:

595

answers:

3

I'm starting to have a look at Silverlight, and I wanted to start small. All of the examples I'd looked at used keyframe animations, so I wanted to try a different type of animation. I was also somewhat unfamiliar with performing animations from code, so I decided to try this out as well. My ultimate goal is to make some kind of animated panel, but for now I'm starting small with just one button:

<UserControl x:Class="TestSilverlight.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300" Background="Azure">
    <Grid x:Name="LayoutRoot" Background="Azure">
        <Button x:Name="btnClick" Content="Animate me!" Height="48" Width="96" Click="btn_Click">
        </Button>
    </Grid>
</UserControl>

I wrote this event handler, which I thoguth was pretty straightforward:

private void btn_Click(object sender, EventArgs e)
{
    Storyboard story = new Storyboard();
    story.RepeatBehavior = new RepeatBehavior(3.0);
    story.Duration = new Duration(TimeSpan.FromSeconds(1.0));

    if (btnClick.RenderTransform == null)
        btnClick.RenderTransform = new TranslateTransform();

    DoubleAnimation xAnim = new DoubleAnimation();
    xAnim.To = 50;
    Storyboard.SetTargetProperty(xAnim, new PropertyPath(TranslateTransform.XProperty));
    Storyboard.SetTarget(xAnim, btnClick.RenderTransform);

    story.Children.Add(xAnim);

    story.Begin();
}

What I expect when I click the button is to see it slide to the right 50 units 3 times. What actually happens is the entire layout disappears, as in the background color along with the button disappears.

If I rewrite the code for the button to start with a RenderTransform, everything works!

<Button x:Name="btnClick" Content="Animate me!" Height="48" Width="96" Click="btn_Click">
    <Button.RenderTransform>
        <TranslateTransform />
    </Button.RenderTransform>
</Button>

What's happening in the first case that causes the failure? Am I doing something fundamentally wrong?

A: 

Last time I worked with Silverlight was in earlier 2008. In Beta versions of Silverlight sometimes the entire layout just disappeared (stayed white and empty) when any error occured, instead of an error message.

Not sure if this is still the case in current versions. Can you (or did you already) step through the code to check if an exception is thrown... or catch it programmatically and render some kind of error message?

Hope I could help you a little bit.

Matthias

Mudu
A: 

I have been looking into pretty much the same thing, and various sources that I have read suggest that you can not add storyboards programmatically. Try Adding it in the XAML, then you could mod it in the code---just make sure to name it so you can access it. You may have to add the transform in the xaml as well. The thing to remember that silverlight is not wpf, it's close but many things are different--just enough to be a pain.

<UserControl x:Class="TestSilverlight.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300" Background="Azure">
    <UserControl.Resources>
        <StoryBoard Name="story" />
    </UserControl.Resources>

<Grid x:Name="LayoutRoot" Background="Azure">
    <Button x:Name="btnClick" Content="Animate me!" Height="48" Width="96" Click="btn_Click">
    </Button>
</Grid>

Muad'Dib
+1  A: 

You can fix the problem by removing the check for "btnClick.RenderTransform == null", and instead always create a new TranslateTransform, or check for "btnClick.RenderTransform is TranslateTransform" instead of null.

The reason you are seeing this error is that by default the Button has an identity transform for its RenderTransform, which happens to be a MatrixTransform. So you are attempting to animate a MatrixTransform as if it were a TranslateTransform.

KeithMahoney
Bah, I should have caught that. Thanks!
OwenP