我应该使用什么控件类型-图像,MediaElement等?
当前回答
在WPF中等待动画的替代方法是:
<ProgressBar Height="20" Width="100" IsIndeterminate="True"/>
它将显示一个动画进度条。
其他回答
我不确定这个问题是否已经解决,但最好的方法是使用WpfAnimatedGid库。这是非常容易,简单和直接的使用。它只需要2行XAML代码和后面的5行c#代码。
您将看到关于如何在那里使用它的所有必要细节。这也是我用来代替重新发明轮子的方法
基本上与上面的PictureBox解决方案相同,但这次使用了在项目中使用嵌入式资源的幕后代码:
在XAML:
<WindowsFormsHost x:Name="_loadingHost">
<Forms:PictureBox x:Name="_loadingPictureBox"/>
</WindowsFormsHost>
在后台代码:
public partial class ProgressIcon
{
public ProgressIcon()
{
InitializeComponent();
var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("My.Namespace.ProgressIcon.gif");
var image = System.Drawing.Image.FromStream(stream);
Loaded += (s, e) => _loadingPictureBox.Image = image;
}
}
谢谢你的帖子Joel,它帮助我解决了WPF对动画gif的不支持。只是添加了一点代码,因为我有一个设置pictureBoxLoading的时间。Image属性,因为Winforms api。
我必须将我的动画gif图像的构建动作设置为“Content”,并将复制到输出目录设置为“如果更新则复制”或“always”。然后在MainWindow()中调用这个方法。唯一的问题是,当我试图处理流时,它给了我一个红包图形而不是我的图像。我必须解决这个问题。这消除了加载BitmapImage并将其更改为Bitmap的痛苦(这显然杀死了我的动画,因为它不再是gif)。
private void SetupProgressIcon()
{
Uri uri = new Uri("pack://application:,,,/WPFTest;component/Images/animated_progress_apple.gif");
if (uri != null)
{
Stream stream = Application.GetContentStream(uri).Stream;
imgProgressBox.Image = new System.Drawing.Bitmap(stream);
}
}
我无法让这个问题最流行的答案(上面由达里奥提出)正常工作。结果是奇怪的、起伏不定的动画和奇怪的工件。 目前为止我找到的最佳解决方案: 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
我修改了迈克·艾希瓦的代码,让它运行得更好。你可以使用它与1帧jpg png bmp或多帧gif。如果你想绑定uri到控件,绑定UriSource属性,或者你想绑定任何内存流,你绑定Source属性,这是一个BitmapImage。
/// <summary>
/// Элемент управления "Изображения", поддерживающий анимированные GIF.
/// </summary>
public class AnimatedImage : Image
{
static AnimatedImage()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(AnimatedImage), new FrameworkPropertyMetadata(typeof(AnimatedImage)));
}
#region Public properties
/// <summary>
/// Получает/устанавливает номер текущего кадра.
/// </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
}
这是一个自定义控件。您需要在WPF应用程序项目中创建它,并在样式中删除模板覆盖。
推荐文章
- 如何从字符串中删除新的行字符?
- 是否已经添加了事件处理程序?
- Lookup()和Dictionary(Of list()的区别
- 如何从我的c#代码运行EXE文件?
- Node.js vs .Net性能
- .NET控制台应用程序中的全局异常处理程序
- 枚举上最常见的c#位操作
- PowerShell脚本在机器上返回。net框架的版本?
- WPF数据网格底部空行
- 用c#创建一个空文件
- 如何改变列表<T>数据IQueryable<T>数据
- 您可以使用反射来查找当前正在执行的方法的名称吗?
- 流。Seek(0, SeekOrigin.Begin)或Position = 0
- 如果查询为空,则最大返回值
- 传递一个实例化的系统。类型作为泛型类的类型参数