Unanswered WPF Images Disappearing

  • Thursday, May 03, 2012 5:27 PM
     
      Has Code

    I'm writing a WPF Page application that on page load creates a series of CroppedBitmaps from a large source bitmap image, for the purposes of creation a 2D sprite like animation.  This creates quite a large number of images in memory.  There are three pages in the application, that transition from one to the other after a set amount of time.  Everything at first seems okay, however, I've noticed that after awhile, some of the images are no longer being displayed.  Each time the page loads, it should be reloading these images into memory, but it seems not to be the case.

    Here's the code of my Animation Class

    namespace MyProgram
    {
        public delegate void NewCustomAnimationFinishedHandler(object sender, NewCustomAnimationEventArgs e);
        public delegate void NewCustomAnimationStartedHandler(object sender, NewCustomAnimationEventArgs e);
    
        public class NewCustomAnimationEventArgs : EventArgs
        {
            public string animKey;
    
            public NewCustomAnimationEventArgs(string key)
            {
                animKey = key;
            }
        }
    
    
        public class NewCustomAnimation : DependencyObject
        {
            #region Public / Privates Variable - Properties
            //public List<BitmapImage> Frames = new List<BitmapImage>();
            public DispatcherTimer animationTimer;
            public int totalFrames;
            public int currentFrame = 0;
    
            public List<Int32Rect> FrameRects;
            public List<CroppedBitmap> Frames;
            public BitmapImage source;
    
            #region Dependency Properties
            public static readonly DependencyProperty CurrentFrameProperty = DependencyProperty.Register("CurrentFrame", typeof(CroppedBitmap), typeof(NewCustomAnimation));
            public CroppedBitmap CurrentFrame
            {
                get { return (CroppedBitmap)GetValue(CurrentFrameProperty); }
                set { SetValue(CurrentFrameProperty, value); }
            }
    
            public static readonly DependencyProperty ImagePathProperty = DependencyProperty.Register("ImagePath", typeof(String), typeof(NewCustomAnimation), new PropertyMetadata("C:\\Childrens\\SteveTheSturgeon\\SwimRight"));
            public String ImagePath
            {
                get { return (String)GetValue(ImagePathProperty); }
                set { SetValue(ImagePathProperty, value); }
            }
            #endregion
    
            #endregion
    
            #region Event Declarations
    
            public event NewCustomAnimationFinishedHandler AnimationCompleted;
            public event NewCustomAnimationStartedHandler AnimationStarted;
            #endregion
    
            #region Constructor
            public NewCustomAnimation(string path)
            {
                FrameRects = new List<Int32Rect>();
                Frames = new List<CroppedBitmap>();
                ImagePath = path;
                LoadImage();
                animationTimer = new DispatcherTimer();
                animationTimer.Interval = TimeSpan.FromMilliseconds(33.33);
                animationTimer.Tick += new EventHandler(animationTimer_Tick);
                currentFrame = 0;
            }
    
            #endregion
    
            #region Public Functions
    
            public void StartAnimation()
            {
                animationTimer.Start();
                currentFrame = 0;
                OnAnimationStarted(new NewCustomAnimationEventArgs("beep"));
            }
    
            public void EndAnimation()
            {
                animationTimer.Stop();
            }
    
            public void FinishAnimation()
            {
                //MessageBox.Show("Killing Animation...");
                animationTimer.Stop();
                animationTimer.Tick -= animationTimer_Tick;
    
                cEventHelper.RemoveAllEventHandlers(this);
    
                Frames.Clear();
                FrameRects.Clear();
            }
    
            protected virtual void OnAnimationCompleted(NewCustomAnimationEventArgs e)
            {
                NewCustomAnimationFinishedHandler tmp = AnimationCompleted;
                if (tmp != null)
                    AnimationCompleted(this, e);
            }
    
            protected virtual void OnAnimationStarted(NewCustomAnimationEventArgs e)
            {
                NewCustomAnimationStartedHandler tmp = AnimationStarted;
                if (tmp != null)
                    AnimationStarted(this, e);
            }
    
            #endregion
    
            #region Private Functions
    
            private void LoadImage()
            {
                source = new BitmapImage(new Uri(ImagePath + "\\sprite.png"));
    
                XmlDocument doc = new XmlDocument();
                doc.Load(ImagePath + "\\sprite.xml");
    
                XmlNodeList animList = doc.GetElementsByTagName("sprite");
    
                foreach (XmlNode node in animList)
                {
                    XmlElement animElement = (XmlElement)node;
    
                    int x = Int32.Parse(animElement.GetAttribute("x"));
                    int y = Int32.Parse(animElement.GetAttribute("y"));
                    int w = Int32.Parse(animElement.GetAttribute("w"));
                    int h = Int32.Parse(animElement.GetAttribute("h"));
                    Int32Rect r = new Int32Rect(x, y, w, h);
                    FrameRects.Add(r);
    
                    totalFrames = FrameRects.Count;
    
                }
    
                foreach (Int32Rect r in FrameRects)
                {
                    CroppedBitmap c;
                    c = new CroppedBitmap(source, r);
                    c.Freeze();
                    Frames.Add(c);
                }
    
                CurrentFrame = Frames[0]; //new CroppedBitmap(source, FrameRects[0]);
                
            }
    
            #endregion
    
            #region Event Handler Methods
            void animationTimer_Tick(object sender, EventArgs e)
            {
                currentFrame++;
                if (currentFrame >= totalFrames)
                {
                    currentFrame = 0;
                    OnAnimationCompleted(new NewCustomAnimationEventArgs("test"));
                }
    
                CurrentFrame = Frames[currentFrame];// new CroppedBitmap(source, FrameRects[currentFrame]);  
            }
    
            #endregion
        }
    }
    

    Any help getting this sorted out would be greatly appreciated!

    James Thompson

All Replies

  • Thursday, May 03, 2012 10:18 PM
     
     
    If you put the project somewhere we can download and debug.

    JP Cowboy Coders Unite!

  • Monday, May 07, 2012 7:40 AM
    Moderator
     
     

    Hi James Thompson,

    Could you share a repro sample with me, it is hard to find the root cause based on above code.

    Best regards,


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.