/// <summary> /// Loads the image thumbnail to image cache in a background thread. /// When the loading is complete, invalidate the item rectangle to make it redraw. /// </summary> /// <param name="index">The index.</param> /// <param name="entry">The entry.</param> /// <param name="cache">The cache.</param> /// <param name="bounds">The bounds.</param> private void LoadImageToCache(int index, Entry entry, ImageCache cache, Rectangle bounds) { BackgroundWorker worker = new BackgroundWorker(); worker.DoWork += delegate(object sender, DoWorkEventArgs args) { Image thumbnailImage = new Bitmap(bounds.Width, bounds.Height); using (Image image = Image.FromFile(entry.PhotoPath)) { this.DrawToFit(Graphics.FromImage(thumbnailImage), image, new Rectangle(0, 0, bounds.Width, bounds.Height)); } cache.AddCachedImage(entry, thumbnailImage); }; worker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs args) { // Start the timer to do the fade in animation. Timer timer = new Timer(); timer.Interval = 1; long initialTimestamp = DateTime.Now.Ticks; timer.Tick += delegate(object s, EventArgs e) { long diff = (DateTime.Now.Ticks - initialTimestamp) / 10000; int alpha = (int)(255 - (255 * diff / PhotoFadeInTime)); if (alpha <= 0) { if (this.PhotoAlphaValues.ContainsKey(entry)) { this.PhotoAlphaValues.Remove(entry); } timer.Stop(); } else { if (this.PhotoAlphaValues.ContainsKey(entry)) { this.PhotoAlphaValues[entry] = alpha; } else { this.PhotoAlphaValues.Add(entry, alpha); } } this.Invalidate(this.GetItemRectangle(index)); }; timer.Start(); }; worker.RunWorkerAsync(); }