Sharker Khaleed Mahmud Silverlight Tips & Tricks

January 1, 2011

93. Animated Vertical Scrollable Content in Silverlight

Filed under: Silverlight — Tags: , — Sharker Khaleed Mahmud | shamrat231 @ 9:52 PM

[tweetmeme source=”shamrat231” only_single=false]

In this entry, I will create a simple animated vertical sliding content. To do this I will start first by creating a simple listbox and then do the binding using MVVM pattern and afterwards apply animation to the listboxitem content from code behind.

You can see the live example here [live demo]

The SOURCE CODE(.zip) is at the end of the page for download.

So lets look at the initial listbox code.

        <ListBox ItemsSource=”{Binding Items}”>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <Image Source=”Images/unknown.png” Height=”100″ />
                        <TextBlock Text=”this is Content” />
                    StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

It basically is a simple data structure but works, now the data need to be binded to a collection. In this case the collection is items eg. ItemsSource=”{Binding Items}”.  In my case, I am going to create a simple view model with this property and bind the view model to the user control i.e views. This can be easily achieved by setting like this.

MainPage.xaml.cs
        public MainPage()
        {
            InitializeComponent();
            this.DataContext = new ItemViewModel();
        }
ItemViewModel.cs

namespace ScrollableContent.ViewModels
{
    public class ItemViewModel
    {
        public ItemViewModel()
        {
       
        }
    }
}

We need a collection say items in the view model which will be binded to the listbox. Now if you go t the Image class, you will notice that the source has type ImageSource.

In other words, the Items need to be like this. The below code would have work if we are only binding the image. We also have text to bind. So a model needs to be created having the properties to be binded to the listbox.

    public class ItemViewModel
    {
        public List<ImageSource> Items { get; set; }

        public ItemViewModel()
        {
            this.Items = new List<ImageSource>();
        }
    }

So the changed code is
    public class ItemViewModel
    {
        public List<ItemModel> Items { get; set; }

        public ItemViewModel()
        {
            this.Items = new List<ItemModel>();
        }
    }

where the ItemModel is

    public class ItemModel
    {
        public ImageSource Source { get; set; }
        public string Description { get; set; }
    }

and to this property is to be binded to the listbox. So the data template need to be changed.

                    <StackPanel Orientation=”Horizontal”>
                        <Image Source=”{Binding Source}” Height=”100″ />
                        <TextBlock Text=”{Binding Description}” />
                    </StackPanel>

Lets add a simple dummy data to check if our Model-View-ViewModel actually works.

        public ItemViewModel()
        {
            this.Items = new List<ItemModel>();
            this.Items.Add(new ItemModel() {
                Source = new BitmapImage(new Uri(“../Images/unknown.png”, UriKind.Relative)),
                Description = “This is some text”,
            });
        }

Now we have that cleared lets add some more data before animation is tried on collection. Instead of adding data on constructor, add all the data in another method for more simplicity. One thing to note here is that the listbox size will increase if we increase the size of the collection. Now restrict the current list box to show only two contents at a time.

        <Canvas>
            <Canvas.Clip>
            <RectangleGeometry RadiusX=”10″ RadiusY=”10″ Rect=”0,0,450,350″ />
            </Canvas.Clip>
            <ListBox ItemsSource=”{Binding Items}” HorizontalAlignment=”Center” VerticalAlignment=”Center”>
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation=”Horizontal” Margin=”0,10,5,5″ Width=”450″ Height=”150″>
                            <Image Source=”{Binding Source}” Width=”100″ Margin=”10″/>
                            <TextBlock Text=”{Binding Description}” VerticalAlignment=”Center” TextWrapping=”Wrap” Width=”300″ Margin=”10″/>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </Canvas>

 Ok, now we want to animate and scroll the content of the listbox we are going to translate the Y property of the listBox. To do this i will write a storyboard and manipulate it using parameter as shown below.

        public static Storyboard VerticalAnimation(UIElement controlToAnimate, double positionToMove)
        {
            DoubleAnimation da = new DoubleAnimation();
            da.Duration = new Duration(TimeSpan.FromSeconds(1));

            Storyboard sb = new Storyboard();
            sb.Duration = new Duration(TimeSpan.FromSeconds(1));
            sb.Children.Add(da);

            Storyboard.SetTarget(da, controlToAnimate);
            Storyboard.SetTargetProperty(da, new PropertyPath(“(UIElement.RenderTransform).(TranslateTransform.Y)”));
            da.To = positionToMove;
            return sb;
        }

Ok, so basically this storyboard will either slide upwards or downwards and we can send a parameter “position to move” on this storyboard. This makes all of it very simple. Add two events and invoke this story board to do the slide up/down effect as shown below…

        int move = 0;
        int imgShown = 2;
        private const int h = 350;

        public MainPage()
        {
            InitializeComponent();
            this.Next.Click += new System.Windows.RoutedEventHandler(Next_Click);
            this.Back.Click += new System.Windows.RoutedEventHandler(Back_Click);
            this.DataContext = new ItemViewModel();
        }

        void Back_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            if (imgShown != 2)
            {
                imgShown -= 2;
                move += h;
                VerticalAnimation(this.Collection, move).Begin();
            }
        }

        void Next_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            if (this.Collection.Items.Count > imgShown)
            {
                imgShown += 2;
                move -= h;
                VerticalAnimation(this.Collection, move).Begin();
            }
        }

This complete the whole coding. Now lets clean the view and move all the parameter to the App.xaml/resource dictionary as you see fit. In this case. after cleaning the view looks like this.

Now you might be wondering what happened to data template.  It is now in the being applied as style. In other words, the data template can now be reused for other types of control beside listbox.

         <DataTemplate x:Key=”ItemContentTemplate”>
            <Grid>
                <StackPanel Orientation=”Horizontal” Margin=”0,10,5,5″ Width=”450″ Height=”150″>
                    <Image Source=”{Binding Source}” Style=”{StaticResource imgStyle}”/>
                    <TextBlock Text=”{Binding Description}” Style=”{StaticResource textStyle}” />
                </StackPanel>
                <HyperlinkButton Content=”Read more” Style=”{StaticResource LinkStyle}” />
            </Grid>
        </DataTemplate>

As always, you can download the source code from here [download link]

Sharker Khaleed Mahmud
Web Developer

Advertisements

6 Comments »

  1. […] Animated Vertical Scrollable Content in Silverlight (Sharker Khaleed Mahmud) […]

    Pingback by Windows Client Developer Roundup 053 for 1/6/2011 - Pete Brown's 10rem.net — January 6, 2011 @ 10:44 PM

  2. […] Animated Vertical Scrollable Content in Silverlight (Sharker Khaleed Mahmud) […]

    Pingback by Linksammlung 13/01/2011 | Silverlight, WPF & .NET — January 13, 2011 @ 9:31 AM

  3. I am trying to put this listbox in one of the pages of a standard Silverlight navigation application. I put the MainPage and App xaml in the Page xaml. The MainPage and App code went into the Page code. It compiles OK and I have the Back and Next buttons showing but the rest is not loading.

    I did not put App startup code in and the following App line in the Page code as it did not work:

    this.Startup += this.Application_Startup;

    Any suggestions?

    Thank You For The Excellent Example!

    Comment by Paul — March 1, 2011 @ 7:56 PM

    • Hi Paul, this should be easy. Say your navigation page is mypage.xaml. So to use the control on that page, just use the page with the listbox in your mypage.xaml as sub usercontrol, thats basically it.

      so xmlns:mynamepace=”project namespace”
      mynamespace:MainPage …..in your mypage.xaml

      Comment by Sharker Khaleed Mahmud | shamrat231 — March 3, 2011 @ 5:23 AM

  4. Let me clarify the question. When putting the listbox in a standard navigation template page, the following code will not populate the listbox.

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
    DataContext = new ItemViewModel();
    }

    Thanks.

    Comment by Paul — March 2, 2011 @ 4:26 PM

  5. Estoy haciendo uno parecido pero es verticalmente y cuando lo muevo se sobrepone, osea que sale del cuadro del listbox pero lo sigo viendo, a diferencia de este que sale del cuadro del listbox y no se puede ver, alguien puede ayudarme con esto

    Comment by Inguelberth — June 14, 2011 @ 6:30 AM


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: