-1

I've been trying to get an animation sequence working for a game for Wpf. Being new at WPF, I didn't find a XAML answer that worked. I managed to piece together some C# code, and it worked but then I found I could not change the Image Source afterwards. I did many searches on the internet, tried things like changing the caching, but nothing had any effect.

In the code below, statement marked "This assignment ignored" is just that. No exception or other error, just stepping through it shows the assignment was not honored. I did find an answer while searching on a related topic (which I'll give in an answer post), but I wanted to post this in hopes of saving other developers a lot of frustration with this issue and how to make a WPF image animation of an explosion. The actual images don't matter, use whatever ones you want.

The XAML

<StackPanel Background="#333333">
    <Button x:Name="boomButton" HorizontalAlignment="Center" 
                    FontSize="24" VerticalAlignment="Bottom" Click="boomButton_Click" >BOOM</Button>
    <Button x:Name="resetButton" HorizontalAlignment="Center" 
                    FontSize="24" VerticalAlignment="Bottom" Click="resetButton_Click" >Reset</Button>

    <Image x:Name="bmb" Source="Images\bomberbase.png" Stretch="None" />
</StackPanel>

C# Backend Code

public partial class MainWindow : Window
{
    public static BitmapImage mBoom1Img, mBoom2Img, mBoom3Img;
    public static BitmapImage mBomberImg, mBlankImg;
    public static BitmapImage mUnknownEnhancementImg, mAirfieldCraterImg;

    public MainWindow()
    {
        InitializeComponent();

        mBoom1Img = BitmapImageFromSource("Images/boom1.png");
        mBoom2Img = BitmapImageFromSource("Images/boom2.png");
        mBoom3Img = BitmapImageFromSource("Images/boom3.png");
        mBomberImg = BitmapImageFromSource("Images/bomberbase.png");
        mBlankImg = BitmapImageFromSource("Images/blank.png");
        mUnknownEnhancementImg = BitmapImageFromSource("Images/unknownEnhancement.png");
        mAirfieldCraterImg = BitmapImageFromSource("Images/airfieldCrater.png");
    }

    public static BitmapImage BitmapImageFromSource(string aRelPath)
    {
        BitmapImage bi3 = new BitmapImage();

        bi3.BeginInit();
        bi3.UriSource = new Uri(aRelPath, UriKind.Relative);
        bi3.EndInit();
        return bi3;
    }


    private void resetButton_Click(object sender, RoutedEventArgs e)
    {
        bmb.Source = mUnknownEnhancementImg;   // This assignment ignored
    }

    private void boomButton_Click(object sender, RoutedEventArgs e)
    {
        ObjectAnimationUsingKeyFrames animation = new ObjectAnimationUsingKeyFrames();
        animation.BeginTime = TimeSpan.FromSeconds(0);
        animation.Duration = new TimeSpan(0, 0, 0, 3, 0);

        DiscreteObjectKeyFrame fbmb = new DiscreteObjectKeyFrame(mBomberImg, TimeSpan.FromMilliseconds(0));
        animation.KeyFrames.Add(fbmb);

        DiscreteObjectKeyFrame f1 = new DiscreteObjectKeyFrame(mBoom1Img, TimeSpan.FromMilliseconds(200));
        animation.KeyFrames.Add(f1);
        DiscreteObjectKeyFrame f2 = new DiscreteObjectKeyFrame(mBoom2Img, TimeSpan.FromMilliseconds(400));
        animation.KeyFrames.Add(f2);
        DiscreteObjectKeyFrame f3 = new DiscreteObjectKeyFrame(mBoom3Img, TimeSpan.FromMilliseconds(600));
        animation.KeyFrames.Add(f3);
        DiscreteObjectKeyFrame f4 = new DiscreteObjectKeyFrame(mBlankImg, TimeSpan.FromMilliseconds(1000));
        animation.KeyFrames.Add(f4);

        animation.Completed += new EventHandler(animation_Complete);
        bmb.BeginAnimation(Image.SourceProperty, animation);
    }

    private void animation_Complete(object sender, EventArgs e)
    {
        // This unlocks the animation's hold on the property!
        //bmb.BeginAnimation(Image.SourceProperty, null);

        bmb.Source = mAirfieldCraterImg;   //  This assignment ignored
    }
}
DrDirt
  • 1
  • 1

1 Answers1

-1

While all the posts I could find revolved around setting options on the bitmap, I happened upon a surprisingly simple answer that seems to work just fine. It seems the animation maintains a lock on the image source even after the animation has ended.

Starting the same animation up with a null argument gets it to "let go" of the Source so that the problem assignment works fine. I don't know of any side effects of this, but I haven't seen any.

    private void animation_Complete(object sender, EventArgs e)
    {
        // This unlocks the animation's hold on the property!
        bmb.BeginAnimation(Image.SourceProperty, null);

        bmb.Source = mAirfieldCraterImg;   //  This assignment works
    }
DrDirt
  • 1
  • 1