在WPF

2013-10-30 32 views
11
我使用在seprate庫 和XAML代碼的gif動畫效果這段代碼在我的主要項目

動畫的Gif:在WPF

<controls:GifImage GifSource="/project;component/Images/my.gif" Stretch="None" /> 

的Gif動畫效果(seprate文件):

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() 
     { 

      _gifDecoder = new GifBitmapDecoder(new Uri(String.Format("pack://application:,,,{0}", 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 
    } 

但我得到錯誤:

The URI prefix is not recognized.

我不知道爲什麼我得到錯誤。請有人幫助我嗎?

回答

23

沒有顯示在WPF動態.gif更簡單的方法 - 使用MediaElement

例子:

<MediaElement x:Name="myGif" MediaEnded="myGif_MediaEnded" UnloadedBehavior="Manual"  Source="file://C:\waiting.GIF" LoadedBehavior="Play" Stretch="None"/> 

如果你想.gif文件到無限循環,但它僅規定有限在.gif文件重複的量,你可以連接MediaEnded,只是重新啓動動畫(請務必設置UnloadedBehaviorManual):

private void myGif_MediaEnded(object sender, RoutedEventArgs e) 
    { 
     myGif.Position = new TimeSpan(0, 0, 1); 
     myGif.Play(); 
    } 
+1

謝謝,但這不是我的問題解決方案。 – UFO

+0

如何指定GIF在屏幕上播放的位置? – zetar

+2

不適用於Gif大於幾KB的問題 – Wobbles

0

試試這個:

<controls:GifImage GifSource="/Images/my.gif" Stretch="None" /> 

BTW,我發現用這種方式來發揮在WPF GIF可能會變形,一些GIF圖像,我不知道爲什麼...

+0

你在哪裏找到控制權? –

+0

這個解決方案可以在這裏找到:https://stackoverflow.com/a/1134340/2772330 –

0

我不能居功這一點,但這裏只有在XAML中這樣做的方法。我在ViewModel中添加了一個「IsBusy」屬性,以在處理過程中顯示/隱藏微調器。

 <Image Name="Spinner" Source="Resources/spinner.gif" RenderTransformOrigin="0.5, 0.5"> 
      <Image.Triggers> 
       <EventTrigger RoutedEvent="FrameworkElement.Loaded"> 
        <EventTrigger.Actions> 
         <BeginStoryboard> 
          <Storyboard Storyboard.TargetName="Spinner" Storyboard.TargetProperty="RenderTransform.(RotateTransform.Angle)"> 
           <DoubleAnimation From="0" To="360" BeginTime="0:0:0" Duration="0:0:2" RepeatBehavior="Forever" /> 
          </Storyboard> 
         </BeginStoryboard> 
        </EventTrigger.Actions> 
       </EventTrigger> 
      </Image.Triggers> 
      <Image.RenderTransform> 
       <RotateTransform Angle="0" /> 
      </Image.RenderTransform> 
      <Image.Style> 
       <Style TargetType="Image"> 
        <Style.Triggers> 
         <DataTrigger Binding="{Binding IsBusy}" Value="False"> 
          <Setter Property="Visibility" Value="Hidden"/> 
         </DataTrigger> 
        </Style.Triggers> 
       </Style> 
      </Image.Style> 
     </Image> 

下面是作者解決方案的link

+0

這只是旋轉圖像(如果源是.gif圖片第一張圖片) –