我一直在試圖從他對GIF動畫的回答讓邁克Eshva的代碼工作,從這裏開始:動畫GIF在VS2010的設計視圖中工作,但有運行時錯誤?
How do I get an animated gif to work in WPF?
這裏重述(包括翻譯的註釋):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Media.Animation;
using System.Windows.Media;
using System.Diagnostics;
namespace WpfBrowserApplication1 {
/// <summary>
/// Control of the "Images", which supports animated GIF.
/// </summary>
public class AnimatedImage : Image {
public AnimatedImage() {
DefaultStyleKeyProperty.OverrideMetadata(typeof(AnimatedImage), new FrameworkPropertyMetadata(typeof(AnimatedImage)));
}
#region Public properties
/// <summary>
/// Gets/sets the number of current frame.
/// </summary>
public int FrameIndex {
get { return (int)GetValue(FrameIndexProperty); }
set { SetValue(FrameIndexProperty, value); }
}
/// <summary>
/// Get the BitmapFrame List.
/// </summary>
public List<BitmapFrame> Frames { get; private set; }
/// <summary>
/// Get or set the repeatBehavior of the animation when source is gif formart.This is a dependency object.
/// </summary>
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
/// <summary>
/// Provides derived classes an opportunity to handle changes to the Source property.
/// </summary>
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();
}
/// <summary>
/// Handles changes to the Source property.
/// </summary>
private static void OnSourceChanged
(DependencyObject dp, DependencyPropertyChangedEventArgs e) {
((AnimatedImage)dp).OnSourceChanged(e);
}
#endregion
#region Dependency Properties
/// <summary>
/// FrameIndex Dependency Property
/// </summary>
public static readonly DependencyProperty FrameIndexProperty =
DependencyProperty.Register(
"FrameIndex",
typeof(int),
typeof(AnimatedImage),
new UIPropertyMetadata(0, ChangingFrameIndex));
/// <summary>
/// Source Dependency Property
/// </summary>
public new static readonly DependencyProperty SourceProperty =
DependencyProperty.Register(
"Source",
typeof(BitmapImage),
typeof(AnimatedImage),
new FrameworkPropertyMetadata(
null,
FrameworkPropertyMetadataOptions.AffectsRender |
FrameworkPropertyMetadataOptions.AffectsMeasure,
OnSourceChanged));
/// <summary>
/// AnimationRepeatBehavior Dependency Property
/// </summary>
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
}
}
這裏是我的網頁的XAML只是試圖展示一個動畫GIF:
<Page x:Class="WpfBrowserApplication1.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:my="clr-namespace:WpfBrowserApplication1"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Title="Page1">
<Grid>
<my:AnimatedImage x:Name="Wait" Source="arrows.gif" Width="16" Height="16" />
</Grid>
</Page>
在Page1的設計視圖中,我很高興地看到動畫gif做它應該做的事情,沒有構建錯誤,沒有設計錯誤,它只是按照它應該的方式工作。只要我啓動頁面以確保它在瀏覽器中正常工作,我會在該行看到以下錯誤:<my:AnimatedImage x:Name="Wait" Source="arrows.gif" Width="16" Height="16" />
'Set property'WpfBrowserApplication1.AnimatedImage.Source'throw a exception。'行號「11」和行位置「21」。
我一直試圖讓它工作一段時間。當項目運行時,我能做些什麼來使圖像動畫化?
嘗試這個。收到NotSupportedException:「URI前綴無法識別。」 – 2010-07-29 15:58:01
我不好,你需要在圖像路徑前加一個「/」來代替:GifSource =「/ SomeImage.gif」。我會在答案中解決它。 – Carlo 2010-07-29 18:10:37
知道這個切換-1到1,現在它工作。 – 2010-07-29 21:13:48