Andrej Tozon's blog

In the Attic


Silverlight Layout States with Reactive Extensions

I’ve been working on several applications where I needed to display several items in a ListBox (or an ItemsControl) at startup, but they had to appear on the screen one by one, with a short delay, not all at once. Using ListBoxItem’s layout states took care of handling how an individual item would appear in the list, but I still needed to handle a short pause between each item being added to the list. Usually I resorted to using a Timer, which sorted out that needed delay for me, but that really felt like hacking that had nothing to do with the real problem.

Reactive Extensions, however, offer a much elegant solution. The GenerateFromTime() construction operator is a close relative to the Generate() operator used in my previous blog entry, except GenerateFromTime() adds an important time dimension to generated sequence – the last parameter in this operator lets you specify a delay between each call to OnNext():

private readonly IObservable<string> numbers = Observable.GenerateWithTime(1, i => i <= 8, i => i + 1, i => i.ToString(), i => TimeSpan.FromSeconds(.3));

The above code snippet will produce an observable sequence of 8 strings, progressing through these strings with a 0.3 seconds delay.

The rest of the code:

private void OnLoaded(object sender, RoutedEventArgs e)

private void AddImage(string image)

Note the ObserveOnDispatcher() operator again – GenerateWithTime uses a timer operating on a background thread so we need to ensure the AddImage() method is called on the UI thread.

Layout states for this sample are kept really basic:

<VisualStateGroup x:Name="LayoutStates">
        <VisualTransition GeneratedDuration="0:0:1">
                <CubicEase EasingMode="EaseOut"/>
    <VisualState x:Name="AfterLoaded"/>
    <VisualState x:Name="BeforeLoaded">
            <DoubleAnimation Duration="0" To="-94" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" Storyboard.TargetName="grid" d:IsOptimized="True"/>
            <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="grid" d:IsOptimized="True"/>
    <VisualState x:Name="BeforeUnloaded"/>

And the final result can be observed by following this link.image

This post has shown how to use Reactive Extensions in Silverlight to gradually fill a ListBox, with a bonus of a nice item entry animation, provided by the layout states.

Download source code from here.