2
votes

In Silverlight (though I think this is applicable to WPF as well) I have an Items Control that has a List of Uris bound to it.

The ItemsPanel is a WrapPanel (from the Silverlight Toolkit) and the DataTemplate contains an Image with it's Source bound.

The databound images display fine.

In xaml for each bound Image I have a storyboard which is started by The Image.Loaded RoutedEvent on an EventTrigger for each Image.

The Storyboard increases the images opacity from 0 to 1 over a period of 1 second.

When this runs all images 'fade in' at the same time.

Question : How can I build in a delay so that the subsequent images animation starts a short while after the previous? (Think of a mexican wave)

Update : Code example coming soon

<ItemsControl x:Name="Items1" ItemsSource="{Binding}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <toolkit:WrapPanel></toolkit:WrapPanel>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Border BorderBrush="#cccccc" BorderThickness="1" Margin="5">
                    <Image x:Name="myImage" Source="{Binding}" Width="100" Height="100" Stretch="Fill">
                        <Image.Triggers>
                            <EventTrigger RoutedEvent="Image.Loaded">
                                <BeginStoryboard>
                                    <Storyboard x:Name="myStoryboard">
                                        <DoubleAnimation Duration="00:00:03"
                            Storyboard.TargetName="myImage" 
                            Storyboard.TargetProperty="Opacity" 
                            From="0" To="1" />
                                    </Storyboard>
                                </BeginStoryboard>

                            </EventTrigger>
                        </Image.Triggers>
                    </Image>
                </Border>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
2

2 Answers

4
votes

You could bind DoubleAnimation.BeginTime to the index of ImageUri in your UriList. Of course you have to use a converter.

class UriIndexConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        int seconds = YourUriList.IndexOf(value); /* or something similar */

        return new TimeSpan(0, 0, seconds);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

In your DoubleAnimation:

BeginTime="{Binding Converter={StaticResource UriIndexConverter}}"
2
votes

My suggestion would be to make a Queue<Storyboard>. That way you can start the first one, and when it fires the "completed" event, you can dequeue the next storyboard and start that, when that finishes it dequeues the next one and starts that, and so on.