private static void AnimatedSourceChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) { Image image = o as Image; if (image != null) { ImageSource oldValue = e.OldValue as ImageSource; ImageSource newValue = e.NewValue as ImageSource; if (oldValue != null) { image.Loaded -= new RoutedEventHandler(ImageBehavior.ImageControlLoaded); image.Unloaded -= new RoutedEventHandler(ImageBehavior.ImageControlUnloaded); AnimationCache.DecrementReferenceCount(oldValue, GetRepeatBehavior(image)); ImageAnimationController animationController = GetAnimationController(image); if (animationController != null) { animationController.Dispose(); } image.Source = null; } if (newValue != null) { image.Loaded += new RoutedEventHandler(ImageBehavior.ImageControlLoaded); image.Unloaded += new RoutedEventHandler(ImageBehavior.ImageControlUnloaded); if (image.IsLoaded) { InitAnimationOrImage(image); } } } }
private static void InitAnimationOrImage(Image imageControl) { ImageAnimationController animationController = GetAnimationController(imageControl); if (animationController != null) { animationController.Dispose(); } SetAnimationController(imageControl, null); SetIsAnimationLoaded(imageControl, false); BitmapSource source = GetAnimatedSource(imageControl) as BitmapSource; bool animateInDesignMode = GetAnimateInDesignMode(imageControl); bool flag3 = !DesignerProperties.GetIsInDesignMode(imageControl) || animateInDesignMode; bool flag4 = IsLoadingDeferred(source); if ((source != null) && (flag3 && !flag4)) { Action action = null; if (source.IsDownloading) { EventHandler handler = null; handler = delegate(object sender, EventArgs args) { source.DownloadCompleted -= handler; InitAnimationOrImage(imageControl); }; source.DownloadCompleted += handler; imageControl.Source = source; return; } ObjectAnimationUsingKeyFrames animation = GetAnimation(imageControl, source); if (animation != null) { if (animation.KeyFrames.Count <= 0) { imageControl.Source = source; } else { if (action == null) { action = () => imageControl.Source = (ImageSource)animation.KeyFrames[0].Value; } TryTwice(action); } animationController = new ImageAnimationController(imageControl, animation, GetAutoStart(imageControl)); SetAnimationController(imageControl, animationController); SetIsAnimationLoaded(imageControl, true); imageControl.RaiseEvent(new RoutedEventArgs(AnimationLoadedEvent, imageControl)); return; } } imageControl.Source = source; if (source != null) { SetIsAnimationLoaded(imageControl, true); imageControl.RaiseEvent(new RoutedEventArgs(AnimationLoadedEvent, imageControl)); } }
private static void ImageControlUnloaded(object sender, RoutedEventArgs e) { Image image = sender as Image; if (image != null) { ImageSource animatedSource = GetAnimatedSource(image); if (animatedSource != null) { AnimationCache.DecrementReferenceCount(animatedSource, GetRepeatBehavior(image)); } ImageAnimationController animationController = GetAnimationController(image); if (animationController != null) { animationController.Dispose(); } } }
private static void InitAnimationOrImage(Image imageControl) { var controller = GetAnimationController(imageControl); if (controller != null) { controller.Dispose(); } SetAnimationController(imageControl, null); SetIsAnimationLoaded(imageControl, false); BitmapSource source = GetAnimatedSource(imageControl) as BitmapSource; bool isInDesignMode = DesignerProperties.GetIsInDesignMode(imageControl); bool animateInDesignMode = GetAnimateInDesignMode(imageControl); bool shouldAnimate = !isInDesignMode || animateInDesignMode; // For a BitmapImage with a relative UriSource, the loading is deferred until // BaseUri is set. This method will be called again when BaseUri is set. bool isLoadingDeferred = IsLoadingDeferred(source, imageControl); if (source != null && shouldAnimate && !isLoadingDeferred) { // Case of image being downloaded: retry after download is complete if (source.IsDownloading) { EventHandler handler = null; handler = (sender, args) => { source.DownloadCompleted -= handler; InitAnimationOrImage(imageControl); }; source.DownloadCompleted += handler; imageControl.Source = source; return; } var animation = GetAnimation(imageControl, source); if (animation != null) { if (animation.KeyFrames.Count > 0) { // For some reason, it sometimes throws an exception the first time... the second time it works. TryTwice(() => imageControl.Source = (ImageSource)animation.KeyFrames[0].Value); } else { imageControl.Source = source; } controller = new ImageAnimationController(imageControl, animation, GetAutoStart(imageControl)); SetAnimationController(imageControl, controller); SetIsAnimationLoaded(imageControl, true); imageControl.RaiseEvent(new RoutedEventArgs(AnimationLoadedEvent, imageControl)); return; } } imageControl.Source = source; if (source != null) { SetIsAnimationLoaded(imageControl, true); imageControl.RaiseEvent(new RoutedEventArgs(AnimationLoadedEvent, imageControl)); } }
private static void SetAnimationController(DependencyObject obj, ImageAnimationController value) { obj.SetValue(AnimationControllerPropertyKey, value); }
private static void InitAnimationOrImage(Image imageControl) { var controller = GetAnimationController(imageControl); if (controller != null) { controller.Dispose(); } SetAnimationController(imageControl, null); BitmapSource source = GetAnimatedSource(imageControl) as BitmapSource; bool isInDesignMode = DesignerProperties.GetIsInDesignMode(imageControl); bool animateInDesignMode = GetAnimateInDesignMode(imageControl); bool shouldAnimate = !isInDesignMode || animateInDesignMode; // For a BitmapImage with a relative UriSource, the loading is deferred until // BaseUri is set. This method will be called again when BaseUri is set. bool isLoadingDeferred = IsLoadingDeferred(source); if (source != null && shouldAnimate && !isLoadingDeferred) { // Case of image being downloaded: retry after download is complete if (source.IsDownloading) { EventHandler handler = null; handler = (sender, args) => { source.DownloadCompleted -= handler; InitAnimationOrImage(imageControl); }; source.DownloadCompleted += handler; imageControl.Source = source; return; } GifFile gifMetadata; var decoder = GetDecoder(source, out gifMetadata) as GifBitmapDecoder; if (decoder != null && decoder.Frames.Count > 1) { var fullSize = GetFullSize(decoder, gifMetadata); int index = 0; var animation = new ObjectAnimationUsingKeyFrames(); var totalDuration = TimeSpan.Zero; BitmapSource baseFrame = null; foreach (var rawFrame in decoder.Frames) { var metadata = GetFrameMetadata(decoder, gifMetadata, index); var frame = MakeFrame(fullSize, rawFrame, metadata, baseFrame); var keyFrame = new DiscreteObjectKeyFrame(frame, totalDuration); animation.KeyFrames.Add(keyFrame); totalDuration += metadata.Delay; switch (metadata.DisposalMethod) { case FrameDisposalMethod.None: case FrameDisposalMethod.DoNotDispose: baseFrame = frame; break; case FrameDisposalMethod.RestoreBackground: if (IsFullFrame(metadata, fullSize)) { baseFrame = null; } else { baseFrame = ClearArea(frame, metadata); } break; case FrameDisposalMethod.RestorePrevious: // Reuse same base frame break; } index++; } animation.Duration = totalDuration; animation.RepeatBehavior = GetActualRepeatBehavior(imageControl, decoder, gifMetadata); if (animation.KeyFrames.Count > 0) { // For some reason, it sometimes throws an exception the first time... the second time it works. TryTwice(() => imageControl.Source = (ImageSource)animation.KeyFrames[0].Value); } else { imageControl.Source = decoder.Frames[0]; } controller = new ImageAnimationController(imageControl, animation, GetAutoStart(imageControl)); SetAnimationController(imageControl, controller); return; } } imageControl.Source = source; }