Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I modified Mike Eshva's code,And I made it work better.You can use it with either 1frame jpg png bmp or mutil-frame gif.If you want bind a uri to the control,bind the UriSource properties or you want bind any in-memory stream that you bind the Source propertie which is a BitmapImage.</p> <pre><code> /// &lt;summary&gt; /// Элемент управления "Изображения", поддерживающий анимированные GIF. /// &lt;/summary&gt; public class AnimatedImage : Image { static AnimatedImage() { DefaultStyleKeyProperty.OverrideMetadata(typeof(AnimatedImage), new FrameworkPropertyMetadata(typeof(AnimatedImage))); } #region Public properties /// &lt;summary&gt; /// Получает/устанавливает номер текущего кадра. /// &lt;/summary&gt; public int FrameIndex { get { return (int)GetValue(FrameIndexProperty); } set { SetValue(FrameIndexProperty, value); } } /// &lt;summary&gt; /// Get the BitmapFrame List. /// &lt;/summary&gt; public List&lt;BitmapFrame&gt; Frames { get; private set; } /// &lt;summary&gt; /// Get or set the repeatBehavior of the animation when source is gif formart.This is a dependency object. /// &lt;/summary&gt; public RepeatBehavior AnimationRepeatBehavior { get { return (RepeatBehavior)GetValue(AnimationRepeatBehaviorProperty); } set { SetValue(AnimationRepeatBehaviorProperty, value); } } public new BitmapImage Source { get { return (BitmapImage)GetValue(SourceProperty); } set { SetValue(SourceProperty, value); } } public Uri UriSource { get { return (Uri)GetValue(UriSourceProperty); } set { SetValue(UriSourceProperty, value); } } #endregion #region Protected interface /// &lt;summary&gt; /// Provides derived classes an opportunity to handle changes to the Source property. /// &lt;/summary&gt; protected virtual void OnSourceChanged(DependencyPropertyChangedEventArgs e) { ClearAnimation(); BitmapImage source; if (e.NewValue is Uri) { source = new BitmapImage(); source.BeginInit(); source.UriSource = e.NewValue as Uri; source.CacheOption = BitmapCacheOption.OnLoad; source.EndInit(); } else if (e.NewValue is BitmapImage) { source = e.NewValue as BitmapImage; } else { return; } BitmapDecoder decoder; if (source.StreamSource != null) { decoder = BitmapDecoder.Create(source.StreamSource, BitmapCreateOptions.DelayCreation, BitmapCacheOption.OnLoad); } else if (source.UriSource != null) { decoder = BitmapDecoder.Create(source.UriSource, BitmapCreateOptions.DelayCreation, BitmapCacheOption.OnLoad); } else { return; } if (decoder.Frames.Count == 1) { base.Source = decoder.Frames[0]; return; } this.Frames = decoder.Frames.ToList(); PrepareAnimation(); } #endregion #region Private properties private Int32Animation Animation { get; set; } private bool IsAnimationWorking { get; set; } #endregion #region Private methods private void ClearAnimation() { if (Animation != null) { BeginAnimation(FrameIndexProperty, null); } IsAnimationWorking = false; Animation = null; this.Frames = null; } private void PrepareAnimation() { Animation = new Int32Animation( 0, this.Frames.Count - 1, new Duration( new TimeSpan( 0, 0, 0, this.Frames.Count / 10, (int)((this.Frames.Count / 10.0 - this.Frames.Count / 10) * 1000)))) { RepeatBehavior = RepeatBehavior.Forever }; base.Source = this.Frames[0]; BeginAnimation(FrameIndexProperty, Animation); IsAnimationWorking = true; } private static void ChangingFrameIndex (DependencyObject dp, DependencyPropertyChangedEventArgs e) { AnimatedImage animatedImage = dp as AnimatedImage; if (animatedImage == null || !animatedImage.IsAnimationWorking) { return; } int frameIndex = (int)e.NewValue; ((Image)animatedImage).Source = animatedImage.Frames[frameIndex]; animatedImage.InvalidateVisual(); } /// &lt;summary&gt; /// Handles changes to the Source property. /// &lt;/summary&gt; private static void OnSourceChanged (DependencyObject dp, DependencyPropertyChangedEventArgs e) { ((AnimatedImage)dp).OnSourceChanged(e); } #endregion #region Dependency Properties /// &lt;summary&gt; /// FrameIndex Dependency Property /// &lt;/summary&gt; public static readonly DependencyProperty FrameIndexProperty = DependencyProperty.Register( "FrameIndex", typeof(int), typeof(AnimatedImage), new UIPropertyMetadata(0, ChangingFrameIndex)); /// &lt;summary&gt; /// Source Dependency Property /// &lt;/summary&gt; public new static readonly DependencyProperty SourceProperty = DependencyProperty.Register( "Source", typeof(BitmapImage), typeof(AnimatedImage), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure, OnSourceChanged)); /// &lt;summary&gt; /// AnimationRepeatBehavior Dependency Property /// &lt;/summary&gt; public static readonly DependencyProperty AnimationRepeatBehaviorProperty = DependencyProperty.Register( "AnimationRepeatBehavior", typeof(RepeatBehavior), typeof(AnimatedImage), new PropertyMetadata(null)); public static readonly DependencyProperty UriSourceProperty = DependencyProperty.Register( "UriSource", typeof(Uri), typeof(AnimatedImage), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure, OnSourceChanged)); #endregion } </code></pre> <p>This is a custom control. You need to create it in WPF App Project,and delete the Template override in style.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload