我应该使用什么控件类型-图像,MediaElement等?
当前回答
这是我的动画图像控制版本。您可以使用标准属性Source来指定图像源。我进一步改进了它。我是俄罗斯人,项目是俄罗斯的,所以评论也是俄语。但是无论如何,你应该能够理解没有注释的一切。:)
/// <summary>
/// Control the "Images", which supports animated GIF.
/// </summary>
public class AnimatedImage : Image
{
#region Public properties
/// <summary>
/// Gets / sets the number of the current frame.
/// </summary>
public int FrameIndex
{
get { return (int) GetValue(FrameIndexProperty); }
set { SetValue(FrameIndexProperty, value); }
}
/// <summary>
/// Gets / sets the image that will be drawn.
/// </summary>
public new ImageSource Source
{
get { return (ImageSource) GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}
#endregion
#region Protected interface
/// <summary>
/// Provides derived classes an opportunity to handle changes to the Source property.
/// </summary>
protected virtual void OnSourceChanged(DependencyPropertyChangedEventArgs aEventArgs)
{
ClearAnimation();
BitmapImage lBitmapImage = aEventArgs.NewValue as BitmapImage;
if (lBitmapImage == null)
{
ImageSource lImageSource = aEventArgs.NewValue as ImageSource;
base.Source = lImageSource;
return;
}
if (!IsAnimatedGifImage(lBitmapImage))
{
base.Source = lBitmapImage;
return;
}
PrepareAnimation(lBitmapImage);
}
#endregion
#region Private properties
private Int32Animation Animation { get; set; }
private GifBitmapDecoder Decoder { get; set; }
private bool IsAnimationWorking { get; set; }
#endregion
#region Private methods
private void ClearAnimation()
{
if (Animation != null)
{
BeginAnimation(FrameIndexProperty, null);
}
IsAnimationWorking = false;
Animation = null;
Decoder = null;
}
private void PrepareAnimation(BitmapImage aBitmapImage)
{
Debug.Assert(aBitmapImage != null);
if (aBitmapImage.UriSource != null)
{
Decoder = new GifBitmapDecoder(
aBitmapImage.UriSource,
BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.Default);
}
else
{
aBitmapImage.StreamSource.Position = 0;
Decoder = new GifBitmapDecoder(
aBitmapImage.StreamSource,
BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.Default);
}
Animation =
new Int32Animation(
0,
Decoder.Frames.Count - 1,
new Duration(
new TimeSpan(
0,
0,
0,
Decoder.Frames.Count / 10,
(int) ((Decoder.Frames.Count / 10.0 - Decoder.Frames.Count / 10) * 1000))))
{
RepeatBehavior = RepeatBehavior.Forever
};
base.Source = Decoder.Frames[0];
BeginAnimation(FrameIndexProperty, Animation);
IsAnimationWorking = true;
}
private bool IsAnimatedGifImage(BitmapImage aBitmapImage)
{
Debug.Assert(aBitmapImage != null);
bool lResult = false;
if (aBitmapImage.UriSource != null)
{
BitmapDecoder lBitmapDecoder = BitmapDecoder.Create(
aBitmapImage.UriSource,
BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.Default);
lResult = lBitmapDecoder is GifBitmapDecoder;
}
else if (aBitmapImage.StreamSource != null)
{
try
{
long lStreamPosition = aBitmapImage.StreamSource.Position;
aBitmapImage.StreamSource.Position = 0;
GifBitmapDecoder lBitmapDecoder =
new GifBitmapDecoder(
aBitmapImage.StreamSource,
BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.Default);
lResult = lBitmapDecoder.Frames.Count > 1;
aBitmapImage.StreamSource.Position = lStreamPosition;
}
catch
{
lResult = false;
}
}
return lResult;
}
private static void ChangingFrameIndex
(DependencyObject aObject, DependencyPropertyChangedEventArgs aEventArgs)
{
AnimatedImage lAnimatedImage = aObject as AnimatedImage;
if (lAnimatedImage == null || !lAnimatedImage.IsAnimationWorking)
{
return;
}
int lFrameIndex = (int) aEventArgs.NewValue;
((Image) lAnimatedImage).Source = lAnimatedImage.Decoder.Frames[lFrameIndex];
lAnimatedImage.InvalidateVisual();
}
/// <summary>
/// Handles changes to the Source property.
/// </summary>
private static void OnSourceChanged
(DependencyObject aObject, DependencyPropertyChangedEventArgs aEventArgs)
{
((AnimatedImage) aObject).OnSourceChanged(aEventArgs);
}
#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 (ImageSource),
typeof (AnimatedImage),
new FrameworkPropertyMetadata(
null,
FrameworkPropertyMetadataOptions.AffectsRender |
FrameworkPropertyMetadataOptions.AffectsMeasure,
OnSourceChanged));
#endregion
}
其他回答
我建议使用WebBrowser控件。
如果gif在网络上,你可以在XAML中设置源代码:
<WebBrowser Source="https://media.giphy.com/media/Ent2j55lyQipa/giphy.gif" />
如果它是一个本地文件,您可以从后台代码创建源代码。
XAML:
<WebBrowser x:Name="WebBrowser" />
后台代码:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
string curDir = Directory.GetCurrentDirectory();
this.WebBrowser.Source = new Uri(String.Format("file:///{0}/10-monkey.gif", curDir));
}
我有这个问题,直到我发现在WPF4,你可以模拟自己的关键帧图像动画。首先,将你的动画分割成一系列图像,并将它们命名为“Image1.gif”,“Image2,gif”,等等。将这些映像导入您的解决方案资源中。我假设您将它们放在图像的默认资源位置。
您将使用Image控件。使用下面的XAML代码。我已经去掉了不重要的部分。
<Image Name="Image1">
<Image.Triggers>
<EventTrigger RoutedEvent="Image.Loaded"
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Duration="0:0:1" Storyboard.TargetProperty="Source" RepeatBehavior="Forever">
<DiscreteObjectKeyFrames KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/Image1.gif"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrames>
<DiscreteObjectKeyFrames KeyTime="0:0:0.25">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/Image2.gif"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrames>
<DiscreteObjectKeyFrames KeyTime="0:0:0.5">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/Image3.gif"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrames>
<DiscreteObjectKeyFrames KeyTime="0:0:0.75">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/Image4.gif"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrames>
<DiscreteObjectKeyFrames KeyTime="0:0:1">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/Image5.gif"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrames>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Image.Triggers>
</Image>
我无法让这个问题最流行的答案(上面由达里奥提出)正常工作。结果是奇怪的、起伏不定的动画和奇怪的工件。 目前为止我找到的最佳解决方案: https://github.com/XamlAnimatedGif/WpfAnimatedGif
你可以用NuGet安装它
WpfAnimatedGif安装包
并使用它,在一个新的名称空间的窗口,你想添加gif图像,并使用它如下所示
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:gif="http://wpfanimatedgif.codeplex.com" <!-- THIS NAMESPACE -->
Title="MainWindow" Height="350" Width="525">
<Grid>
<!-- EXAMPLE USAGE BELOW -->
<Image gif:ImageBehavior.AnimatedSource="Images/animated.gif" />
这个包非常简洁,你可以像下面这样设置一些属性
<Image gif:ImageBehavior.RepeatBehavior="3x"
gif:ImageBehavior.AnimatedSource="Images/animated.gif" />
你也可以在你的代码中使用它:
var image = new BitmapImage();
image.BeginInit();
image.UriSource = new Uri(fileName);
image.EndInit();
ImageBehavior.SetAnimatedSource(img, image);
编辑:Silverlight支持
根据josh2112的评论,如果你想在Silverlight项目中添加GIF动画支持,请使用github.com/XamlAnimatedGif/XamlAnimatedGif
你可以尝试使用web浏览器UI控件,并设置html字符串为html图像标签…
XML:
<WebBrowser Name="webBrowser1"/>
c#: f
webBrowser1.NavigateToString(
@"<img src=""arrow-24.png""/>"
);
这是我的动画图像控制版本。您可以使用标准属性Source来指定图像源。我进一步改进了它。我是俄罗斯人,项目是俄罗斯的,所以评论也是俄语。但是无论如何,你应该能够理解没有注释的一切。:)
/// <summary>
/// Control the "Images", which supports animated GIF.
/// </summary>
public class AnimatedImage : Image
{
#region Public properties
/// <summary>
/// Gets / sets the number of the current frame.
/// </summary>
public int FrameIndex
{
get { return (int) GetValue(FrameIndexProperty); }
set { SetValue(FrameIndexProperty, value); }
}
/// <summary>
/// Gets / sets the image that will be drawn.
/// </summary>
public new ImageSource Source
{
get { return (ImageSource) GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}
#endregion
#region Protected interface
/// <summary>
/// Provides derived classes an opportunity to handle changes to the Source property.
/// </summary>
protected virtual void OnSourceChanged(DependencyPropertyChangedEventArgs aEventArgs)
{
ClearAnimation();
BitmapImage lBitmapImage = aEventArgs.NewValue as BitmapImage;
if (lBitmapImage == null)
{
ImageSource lImageSource = aEventArgs.NewValue as ImageSource;
base.Source = lImageSource;
return;
}
if (!IsAnimatedGifImage(lBitmapImage))
{
base.Source = lBitmapImage;
return;
}
PrepareAnimation(lBitmapImage);
}
#endregion
#region Private properties
private Int32Animation Animation { get; set; }
private GifBitmapDecoder Decoder { get; set; }
private bool IsAnimationWorking { get; set; }
#endregion
#region Private methods
private void ClearAnimation()
{
if (Animation != null)
{
BeginAnimation(FrameIndexProperty, null);
}
IsAnimationWorking = false;
Animation = null;
Decoder = null;
}
private void PrepareAnimation(BitmapImage aBitmapImage)
{
Debug.Assert(aBitmapImage != null);
if (aBitmapImage.UriSource != null)
{
Decoder = new GifBitmapDecoder(
aBitmapImage.UriSource,
BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.Default);
}
else
{
aBitmapImage.StreamSource.Position = 0;
Decoder = new GifBitmapDecoder(
aBitmapImage.StreamSource,
BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.Default);
}
Animation =
new Int32Animation(
0,
Decoder.Frames.Count - 1,
new Duration(
new TimeSpan(
0,
0,
0,
Decoder.Frames.Count / 10,
(int) ((Decoder.Frames.Count / 10.0 - Decoder.Frames.Count / 10) * 1000))))
{
RepeatBehavior = RepeatBehavior.Forever
};
base.Source = Decoder.Frames[0];
BeginAnimation(FrameIndexProperty, Animation);
IsAnimationWorking = true;
}
private bool IsAnimatedGifImage(BitmapImage aBitmapImage)
{
Debug.Assert(aBitmapImage != null);
bool lResult = false;
if (aBitmapImage.UriSource != null)
{
BitmapDecoder lBitmapDecoder = BitmapDecoder.Create(
aBitmapImage.UriSource,
BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.Default);
lResult = lBitmapDecoder is GifBitmapDecoder;
}
else if (aBitmapImage.StreamSource != null)
{
try
{
long lStreamPosition = aBitmapImage.StreamSource.Position;
aBitmapImage.StreamSource.Position = 0;
GifBitmapDecoder lBitmapDecoder =
new GifBitmapDecoder(
aBitmapImage.StreamSource,
BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.Default);
lResult = lBitmapDecoder.Frames.Count > 1;
aBitmapImage.StreamSource.Position = lStreamPosition;
}
catch
{
lResult = false;
}
}
return lResult;
}
private static void ChangingFrameIndex
(DependencyObject aObject, DependencyPropertyChangedEventArgs aEventArgs)
{
AnimatedImage lAnimatedImage = aObject as AnimatedImage;
if (lAnimatedImage == null || !lAnimatedImage.IsAnimationWorking)
{
return;
}
int lFrameIndex = (int) aEventArgs.NewValue;
((Image) lAnimatedImage).Source = lAnimatedImage.Decoder.Frames[lFrameIndex];
lAnimatedImage.InvalidateVisual();
}
/// <summary>
/// Handles changes to the Source property.
/// </summary>
private static void OnSourceChanged
(DependencyObject aObject, DependencyPropertyChangedEventArgs aEventArgs)
{
((AnimatedImage) aObject).OnSourceChanged(aEventArgs);
}
#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 (ImageSource),
typeof (AnimatedImage),
new FrameworkPropertyMetadata(
null,
FrameworkPropertyMetadataOptions.AffectsRender |
FrameworkPropertyMetadataOptions.AffectsMeasure,
OnSourceChanged));
#endregion
}
推荐文章
- 如何为构造函数定制Visual Studio的私有字段生成快捷方式?
- 为什么Visual Studio 2015/2017/2019测试运行器没有发现我的xUnit v2测试
- AppSettings从.config文件中获取值
- 如何检查IEnumerable是否为空或空?
- 没有ListBox。SelectionMode="None",是否有其他方法禁用列表框中的选择?
- 在c#代码中设置WPF文本框的背景颜色
- 如何在iis7应用程序池中设置。net Framework 4.5版本
- 如何分裂()一个分隔字符串到一个列表<字符串>
- 如何指定最小值,但没有使用范围数据注释属性的最大小数?
- 如何在PowerShell中获得本地主机名?
- 为什么在Java和。net中不能修改字符串?
- 禁用Visual Studio 2015额外调试选项
- 'throw'和'throw new Exception()'的区别
- c# int到字节[]
- 如何跟踪log4net问题