Question

I want to crate a simple flip-book animation in WPF. A flip-book animation just flips between multiple images (eg. classical animation or an animated gif). Note: I am not trying to create a Page Curl animation.

The set of images comes from a List collection, and is not know at compile time.

As such, I was thinking it would be good to start with an ItemsControl bound to my list of images, and then somehow cycle through them with a storyboard animation. However, I am running into a lot of issues with this, and feeling like there might be a better way.

Has anyone done this before, or have ideas for solutions? Thanks!

Was it helpful?

Solution

It might be easier to use a DispatcherTimer. Storyboards are good for animating properties, but they do not work so well with lists and ItemsControls.

I have tested the following approach, and it seems to work well. First put each image into a view-model wrapper with a Visibility property.

public class ImageViewModel : INotifyPropertyChanged
{
    public string ImagePath { get; set; }

    public Visibility Visibility
    {
        get { return _vis; }
        set
        {
            _vis = value;
            RaisePropertyChanged("Visibility");
        }
    }
    private Visibility _vis = Visibility.Collapsed;

    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChanged(string prop)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(prop));
    }
}

So your main view model would have a list of the image view models:

public class FlipBookViewModel
{
    public List<ImageViewModel> FlipBookImages { get; private set; }

    public FlipBookViewModel(string[] imagePaths)
    {
        FlipBookImages = imagePaths.Select(imagePath => new ImageViewModel 
           { ImagePath = imagePath }
        ).ToList();
    }
}

Then, in the page, simply place them on top of each other by using a Grid as the ItemsPanel:

<ItemsControl ItemsSource="{Binding FlipBookImages}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Image Source="{Binding ImagePath}" Visibility="{Binding Visibility}" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

To start the flip book, fire up the DispatcherTimer. Something like this:

var dispatcherTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(100) };
int i=0;
dispatcherTimer.Tick += (sender, args) => {
    if (i>0) 
        FlipBookImages[i-1].Visibility = Visibility.Collapsed;
    if (i>=FlipBookImages.Count) 
       dispatcherTimer.Stop();
    else 
       FlipBookImages[i].Visibility = Visibility.Visible;
    i++;
};
dispatcherTimer.Start();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top