【问题标题】:How do I get this WPF .gif to play on update?如何让这个 WPF .gif 在更新时播放?
【发布时间】:2023-04-08 20:14:02
【问题描述】:

问题:

  • 为什么我的.gif 在使用GifSourcePropertyChanged 更新时会加载,但无法播放?

关于.gif加载:
目前我已经使用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(我不记得是哪个问题,WPF.gifs 上有几个问题)。 GifImage 是唯一没有大量错误的课程(至少对我而言)。

【问题讨论】:

    标签: c# wpf xaml binding animated-gif


    【解决方案1】:

    不确定您的代码有什么问题,但您可以尝试改用this attached property

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

    【讨论】:

    • 嗯...看起来很有趣。这实际上是我还没看过的一篇文章。我去看看。谢谢!
    • 好吧,现在实际播放的是.gif。图像质量仍然非常差(可能会更糟)。它类似于带有失焦镜头的电视静态。文章还说框架交易的平台有限(7和vista)。因此,我不确定我是否可以使用它。在没有更新的平台上会发生什么?
    • 这很奇怪...当我删除 GifImage 类和 local:GifImage 时,新代码停止工作。
    • 如果您不在 Win7 上,它只会使用 100 毫秒的默认帧持续时间(如 GifImage)。我不知道为什么质量很差,我没有这个问题(也许图像本身质量很差?)。无论如何,我看不出它与 GifImage 有什么关系……你可以在普通的 Image 控件上使用附加属性,你根本不需要 GifImage
    • 是的,我的设置与您博客中的完全一样。轻松剪切和粘贴工作。我会在一分钟后发布图像质量差异的屏幕截图。
    猜你喜欢
    • 1970-01-01
    • 2021-09-23
    • 1970-01-01
    • 2018-06-05
    • 2011-07-30
    • 2013-12-23
    • 2022-11-14
    • 2014-02-11
    • 2019-05-01
    相关资源
    最近更新 更多