Как я могу получить этот WPF .gif, чтобы играть при обновлении? - PullRequest
1 голос
/ 23 апреля 2011

Вопрос:

  • Почему мой .gif загружается, но не воспроизводится при обновлении с использованием GifSourcePropertyChanged?

О .gif loading:
В настоящее время я использую U.IsValidURL(), чтобы удержать new Uri от броска Exception.Это потому, что мне нужно GifImage чтобы загрузить приложение, а затем обновить его с ViewModel.Все идет нормально до тех пор, пока не будет вызван GifSourcePropertyChanged, затем обновится local:GifImage, но .gif не будет воспроизводиться (я думаю, что он загружается, когда MediaElement загружается параллельно, а local:GifImage становится черным там, где .gifПредположим, чтобы загрузить).Если я жестко закодирую образец Uri с самого начала, local:GifImage загружается и воспроизводится просто отлично.

Пример XAML:

<local:GifImage 
        GifSource="{    
            Binding Path=myGifImage, 
            UpdateSourceTrigger=PropertyChanged, 
            Mode=OneWay}"
        AutoStart="True"/>

Пример ViewModel:

public class ViewModel: INotifyPropertyChanged
{                   
    private string _myGifImage; 

    public string myGifImage
    {
        get { return this._myGifImage; }
        set
        {
            this._myGifImage = value;
            this.OnPropertyChanged("myGifImage");
        }
    }
}

Пример класса GifImage:

public class GifImage : Image
{
    #region Memmbers

    private GifBitmapDecoder _gifDecoder;
    private Int32Animation _animation;
    private bool _isInitialized;

    #endregion Memmbers

    #region Properties

    private int FrameIndex
    {
        get { return (int)GetValue(FrameIndexProperty); }
        set { SetValue(FrameIndexProperty, value); }
    }

    private static readonly DependencyProperty FrameIndexProperty =
     DependencyProperty.Register("FrameIndex", typeof(int), typeof(GifImage), new FrameworkPropertyMetadata(0, new PropertyChangedCallback(ChangingFrameIndex)));

    private static void ChangingFrameIndex(DependencyObject obj, DependencyPropertyChangedEventArgs ev)
    {
        GifImage image = obj as GifImage;
        image.Source = image._gifDecoder.Frames[(int)ev.NewValue];
    }

    /// <summary>
    /// Defines whether the animation starts on it's own
    /// </summary>
    public bool AutoStart
    {
        get { return (bool)GetValue(AutoStartProperty); }
        set { SetValue(AutoStartProperty, value); }
    }

    public static readonly DependencyProperty AutoStartProperty =
     DependencyProperty.Register("AutoStart", typeof(bool), typeof(GifImage), new UIPropertyMetadata(false, AutoStartPropertyChanged));

    private static void AutoStartPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        if ((bool)e.NewValue)
            (sender as GifImage).StartAnimation();
    }

    public string GifSource
    {
        get { return (string)GetValue(GifSourceProperty); }
        set { SetValue(GifSourceProperty, value); }
    }

    public static readonly DependencyProperty GifSourceProperty =
     DependencyProperty.Register("GifSource", typeof(string), typeof(GifImage), new UIPropertyMetadata(string.Empty, GifSourcePropertyChanged));

    private static void GifSourcePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        // CARLO 20100622: Reinitialize animation everytime image is changed
        (sender as GifImage).Initialize();
    }

    #endregion Properties

    #region Private Instance Methods

    private void Initialize()
    {

        if (U.IsValidURL(this.GifSource, UriKind.Absolute))
        {
            _gifDecoder = new GifBitmapDecoder(
                new Uri(this.GifSource),
                BitmapCreateOptions.PreservePixelFormat,
                BitmapCacheOption.Default);
            _animation = new Int32Animation(0, _gifDecoder.Frames.Count - 1, new Duration(new TimeSpan(0, 0, 0, _gifDecoder.Frames.Count / 10, (int)((_gifDecoder.Frames.Count / 10.0 - _gifDecoder.Frames.Count / 10) * 1000))));
            _animation.RepeatBehavior = RepeatBehavior.Forever;
            this.Source = _gifDecoder.Frames[0];

            _isInitialized = true;
        }

    }

    #endregion Private Instance Methods

    #region Public Instance Methods

    /// <summary>
    /// Shows and starts the gif animation
    /// </summary>
    public void Show()
    {
        this.Visibility = Visibility.Visible;
        this.StartAnimation();
    }

    /// <summary>
    /// Hides and stops the gif animation
    /// </summary>
    public void Hide()
    {
        this.Visibility = Visibility.Collapsed;
        this.StopAnimation();
    }

    /// <summary>
    /// Starts the animation
    /// </summary>
    public void StartAnimation()
    {
        if (!_isInitialized)
            this.Initialize();

        BeginAnimation(FrameIndexProperty, _animation);
    }

    /// <summary>
    /// Stops the animation
    /// </summary>
    public void StopAnimation()
    {
        BeginAnimation(FrameIndexProperty, null);
    }

    #endregion Public Instance Methods
}  

Я получил GifImage откуда-то на SO (я не могу вспомнить, какой вопрос, есть несколько на WPF и .gifs).GifImage был единственным классом, у которого не было тонны ошибок (по крайней мере, для меня).

1 Ответ

2 голосов
/ 23 апреля 2011

Не уверен, в чем проблема с вашим кодом, но вы можете попробовать использовать это присоединенное свойство вместо:

<Image my:ImageBehavior.AnimatedSource="{Binding Path=myGifImage}"/>
...