locked
Smooth Storyboard animations RRS feed

  • Question

  • Hi,

    I am new to Silverlight animations and I have developed a very simple animation that changes the with of a user control that is hosted by a Popup.
    My intention was to simulate a very simple sliding panel. below is my code:

    sb = new Storyboard();
    dx = new DoubleAnimation();
    dx.From = 0;
    dx.To = testControl.Width;
    dx.Duration = new Duration(new TimeSpan(0,0,2));
    dx.AutoReverse = false;

    It is working but the Popup is not appearing smoothly it is appearing hoping and blinking.

    How can I make this animation work smoothly like Visual Studio and its solution explorer.

    Thanks in advance

    Tuesday, March 17, 2009 3:24 PM

Answers

  • Hi,

    I have put a quick test project together to test your code and it seems fairly smooth, there are a few changes I would make such as simplifying the showPopup_Click() method. i.e. move the call to createSB() and setting the PopupTest.Child in the constructor, this is what I have:public Page()

    {

    InitializeComponent();

    createSb();

    // Set the Child property of Popup to an instance of MyControl.

    if (PopupTest.Child == null)

    {

    PopupTest.Child = testControl;

    // Set where the popup will show up on the screen.

    PopupTest.VerticalOffset = 100;

    PopupTest.HorizontalOffset = 100;

    }

    }

    private void createSb()

    {

    testControl =
    new MyPanel();

    testControl.Name = "TestePopup";

    sb = new Storyboard();dx = new DoubleAnimation();

    dx.From = 0;

    dx.To = testControl.Width;

    dx.Duration =
    new Duration(new TimeSpan(0, 0, 2));

    dx.AutoReverse = false;

    Storyboard.SetTargetName(dx, "TestePopup");Storyboard.SetTargetProperty(dx, new PropertyPath(UserControl.WidthProperty));

    sb.Children.Add(dx);

    if (((Storyboard)testControl.LayoutRoot.Resources["ShowPopupResorce"]) == null)

    testControl.LayoutRoot.Resources.Add("ShowPopupResorce", sb);

    }

    private void showPopup_Click(object sender, RoutedEventArgs e)

    {

    testControl.Width = 0;

    Storyboard sb = (Storyboard)testControl.LayoutRoot.Resources["ShowPopupResorce"];

    // Open the popup.

    PopupTest.IsOpen = true;

    sb.Begin();

    }

     

    Tuesday, March 17, 2009 4:39 PM
  • Hello again,

    Well basically you have a Canvas as your Root element with a Grid immediately within this so you can do all your normal layout.  In the Canvas we add your TestControl and hide/show it by changing its Visibility property like this:

    <UserControl x:Class="ExpandingPanel.Page"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Width="400" Height="300">

    <Canvas x:Name="LayoutRoot" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">

    <Grid>

    <Border BorderThickness="5" BorderBrush="Black">

    <StackPanel Background="White">

    <TextBlock Margin="5" Text="Popup Test" />

    <Button Content="Open PopUp" Click="showPopup_Click" />

    <Button Content="Close PopUp" Click="closePopup_Click" />

    </StackPanel>

    </Border>

    </Grid>

    </Canvas>

    </UserControl>

    And in your C#:

    public partial class Page : UserControl

    {

    private Storyboard sb;

    private DoubleAnimation dx;

    private MyPanel testControl;public Page()

    {

    InitializeComponent();

    createSb();

    testControl.SetValue(
    Canvas.LeftProperty, 100d);testControl.SetValue(Canvas.TopProperty, 100d);

    LayoutRoot.Children.Add(testControl);

    }

    private void createSb()

    {

    testControl =
    new MyPanel();

    testControl.Name = "TestePopup";

    sb = new Storyboard();dx = new DoubleAnimation();

    dx.From = 0;

    dx.To = testControl.Width;

    dx.Duration =
    new Duration(new TimeSpan(0, 0, 2));

    dx.AutoReverse = false;

    Storyboard.SetTargetName(dx, "TestePopup");Storyboard.SetTargetProperty(dx, new PropertyPath(UserControl.WidthProperty));

    sb.Children.Add(dx);

    if (((Storyboard)testControl.LayoutRoot.Resources["ShowPopupResorce"]) == null)

    testControl.LayoutRoot.Resources.Add("ShowPopupResorce", sb);

    }

    private void showPopup_Click(object sender, RoutedEventArgs e)

    {

    testControl.Width = 0;

    Storyboard sb = (Storyboard)testControl.LayoutRoot.Resources["ShowPopupResorce"];

    // Open the popup.

    testControl.Visibility = Visibility.Visible;

    sb.Begin();

    }

    private void closePopup_Click(object sender, RoutedEventArgs e)

    {

    }

    Its a good way to do this and you can have any control you want in your expanding panel.

     

    Tuesday, March 17, 2009 10:00 PM

All replies

  • I dont think the Popup control is the best element to host you user control, you would be better off using a Canvas. Could you post your XAML to help me?
    Tuesday, March 17, 2009 3:47 PM
  • Hi

    The Home.xaml is like this:

    <UserControl x:Class="SiverlightFX.Home"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Width="400" Height="300" xmlns:System="clr-namespace:System;assembly=mscorlib">
        <Grid x:Name="LayoutRoot">
            <Border BorderThickness="5" BorderBrush="Black">
                <StackPanel Background="White">
                    <TextBlock Margin="5" Text="Popup Test" />
                    <Button Content="Open PopUp" Click="showPopup_Click" />
                    <Button Content="Close PopUp" Click="closePopup_Click" />
                    <Popup x:Name="PopupTest" IsOpen="False"/>
                </StackPanel>
            </Border>
        </Grid>
    </UserControl>

    The code to create the storyboard is like this:

            private void createSb() {

                testControl.Name = "TestePopup";

                sb = new Storyboard();
                dx = new DoubleAnimation();
                dx.From = 0;
                dx.To = testControl.Width;
                dx.Duration = new Duration(new TimeSpan(0,0,2));
                dx.AutoReverse = false;

                Storyboard.SetTargetName( dx, "TestePopup" );
                Storyboard.SetTargetProperty( dx, new PropertyPath(UserControl.WidthProperty) );
                sb.Children.Add(dx);

                if( ((Storyboard) testControl.LayoutRoot.Resources["ShowPopupResorce"]) == null )
                    testControl.LayoutRoot.Resources.Add("ShowPopupResorce", sb);
            }

            private void showPopup_Click( object sender, RoutedEventArgs e ) {

                createSb();

                // Set the Child property of Popup to an instance of MyControl.
                if( PopupTest.Child == null ) {

                    PopupTest.Child = testControl;

                    // Set where the popup will show up on the screen.
                    PopupTest.VerticalOffset = 100;
                    PopupTest.HorizontalOffset = 100;
                }

                testControl.Width = 0;
                Storyboard sb = (Storyboard) testControl.LayoutRoot.Resources["ShowPopupResorce"];

                // Open the popup.
                PopupTest.IsOpen = true;
                sb.Begin();
            }

    Thanks for you answer.

    Tuesday, March 17, 2009 3:57 PM
  • Hi,

    I have put a quick test project together to test your code and it seems fairly smooth, there are a few changes I would make such as simplifying the showPopup_Click() method. i.e. move the call to createSB() and setting the PopupTest.Child in the constructor, this is what I have:public Page()

    {

    InitializeComponent();

    createSb();

    // Set the Child property of Popup to an instance of MyControl.

    if (PopupTest.Child == null)

    {

    PopupTest.Child = testControl;

    // Set where the popup will show up on the screen.

    PopupTest.VerticalOffset = 100;

    PopupTest.HorizontalOffset = 100;

    }

    }

    private void createSb()

    {

    testControl =
    new MyPanel();

    testControl.Name = "TestePopup";

    sb = new Storyboard();dx = new DoubleAnimation();

    dx.From = 0;

    dx.To = testControl.Width;

    dx.Duration =
    new Duration(new TimeSpan(0, 0, 2));

    dx.AutoReverse = false;

    Storyboard.SetTargetName(dx, "TestePopup");Storyboard.SetTargetProperty(dx, new PropertyPath(UserControl.WidthProperty));

    sb.Children.Add(dx);

    if (((Storyboard)testControl.LayoutRoot.Resources["ShowPopupResorce"]) == null)

    testControl.LayoutRoot.Resources.Add("ShowPopupResorce", sb);

    }

    private void showPopup_Click(object sender, RoutedEventArgs e)

    {

    testControl.Width = 0;

    Storyboard sb = (Storyboard)testControl.LayoutRoot.Resources["ShowPopupResorce"];

    // Open the popup.

    PopupTest.IsOpen = true;

    sb.Begin();

    }

     

    Tuesday, March 17, 2009 4:39 PM
  • Thanks Dan,

    I am surprised that you considered it smooth. I my machine it is hopping and blinking. I any case I will make you changes and see what the results.

    Do you really think that a Canvas will be more appropriate ??? Why ???

    Thank you very much

     

    Tuesday, March 17, 2009 4:48 PM
  • The Popup is a bad control and has a few bugs in it, for example you cannot have certain controls in a Popup such as the Combobox and DatePicker.  If you do not plan to have these controls in your Popup then you will be okay, otherwise it causes Silverlight to crash.

    Your code seemed smooth enough, is it jerky on your machine?  You didn't post your testControl class so I do not know how complicated this is, I simply tested it with a single TextBlock.

    Tuesday, March 17, 2009 4:59 PM
  • Hi,

    Yes it is realy jerky. I will test it in another machine.

    The test control is very simple it only has afew borders. You can see it below:


    <UserControl x:Class="SiverlightFX.TestControl"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Width="400" Height="300">
        <Grid x:Name="LayoutRoot">
            <Border BorderThickness="2,2,2,2" BorderBrush="#FF595959" Background="#FF595959" CornerRadius="5,5,5,5" Padding="1,1,1,1">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="20"></RowDefinition>
                        <RowDefinition Height="*"></RowDefinition>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="100"></ColumnDefinition>
                        <ColumnDefinition Width="*"></ColumnDefinition>
                        <ColumnDefinition Width="100"></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                   
                    <StackPanel Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" Margin="5,2,5,2">
                        <StackPanel Orientation="Horizontal" >
                            <TextBlock Text="Aplicação" Foreground="#FFFCFAFA" />
                        </StackPanel>
                    </StackPanel>
                    <Border Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" BorderThickness="2,2,2,2" BorderBrush="#FF595959" Background="#FF2D2D2D" CornerRadius="5,5,5,5" Margin="2,2,2,2" Padding="1,1,1,1">
                        <StackPanel Orientation="Vertical" >
                            <TextBlock Text="Teste de Popup" Foreground="#FFFCFAFA" />
                        </StackPanel>
                    </Border>
                   
                </Grid>
            </Border>
        </Grid>
    </UserControl>

     

    Tuesday, March 17, 2009 5:23 PM
  • Hi Dan,

    You are are right. I ran the project at home and it is really smooth. At home a have a Core Duo with 8 Gb of RAM in a Vista Ultimate. At work I have a Windows XP with 2 GB.

    The difference is absurd. Is there any issue associated with Windows XP and Silverlight ??? This is the first application that I can see any difference between the two machines. Except of course that at home things run faster.

    Thanks,

     

    Tuesday, March 17, 2009 8:35 PM
  • Hi,

    One more thing. How can I make a Canvas Popup ???

    Thanks

     

    Tuesday, March 17, 2009 9:25 PM
  • Hello again,

    Well basically you have a Canvas as your Root element with a Grid immediately within this so you can do all your normal layout.  In the Canvas we add your TestControl and hide/show it by changing its Visibility property like this:

    <UserControl x:Class="ExpandingPanel.Page"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Width="400" Height="300">

    <Canvas x:Name="LayoutRoot" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">

    <Grid>

    <Border BorderThickness="5" BorderBrush="Black">

    <StackPanel Background="White">

    <TextBlock Margin="5" Text="Popup Test" />

    <Button Content="Open PopUp" Click="showPopup_Click" />

    <Button Content="Close PopUp" Click="closePopup_Click" />

    </StackPanel>

    </Border>

    </Grid>

    </Canvas>

    </UserControl>

    And in your C#:

    public partial class Page : UserControl

    {

    private Storyboard sb;

    private DoubleAnimation dx;

    private MyPanel testControl;public Page()

    {

    InitializeComponent();

    createSb();

    testControl.SetValue(
    Canvas.LeftProperty, 100d);testControl.SetValue(Canvas.TopProperty, 100d);

    LayoutRoot.Children.Add(testControl);

    }

    private void createSb()

    {

    testControl =
    new MyPanel();

    testControl.Name = "TestePopup";

    sb = new Storyboard();dx = new DoubleAnimation();

    dx.From = 0;

    dx.To = testControl.Width;

    dx.Duration =
    new Duration(new TimeSpan(0, 0, 2));

    dx.AutoReverse = false;

    Storyboard.SetTargetName(dx, "TestePopup");Storyboard.SetTargetProperty(dx, new PropertyPath(UserControl.WidthProperty));

    sb.Children.Add(dx);

    if (((Storyboard)testControl.LayoutRoot.Resources["ShowPopupResorce"]) == null)

    testControl.LayoutRoot.Resources.Add("ShowPopupResorce", sb);

    }

    private void showPopup_Click(object sender, RoutedEventArgs e)

    {

    testControl.Width = 0;

    Storyboard sb = (Storyboard)testControl.LayoutRoot.Resources["ShowPopupResorce"];

    // Open the popup.

    testControl.Visibility = Visibility.Visible;

    sb.Begin();

    }

    private void closePopup_Click(object sender, RoutedEventArgs e)

    {

    }

    Its a good way to do this and you can have any control you want in your expanding panel.

     

    Tuesday, March 17, 2009 10:00 PM
  • Hi Dan

    I would like to thank you very much for answers. Have a nice day.

    Marcus Baffa

    Wednesday, March 18, 2009 2:41 PM