我应该使用什么控件类型-图像,MediaElement等?


当前回答

GifImage.Initialize()方法的小改进,该方法从GIF元数据中读取适当的帧定时。

    private void Initialize()
    {
        _gifDecoder = new GifBitmapDecoder(new Uri("pack://application:,,," + this.GifSource), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);

        int duration=0;
        _animation = new Int32AnimationUsingKeyFrames();
        _animation.KeyFrames.Add(new DiscreteInt32KeyFrame(0, KeyTime.FromTimeSpan(new TimeSpan(0))));
        foreach (BitmapFrame frame in _gifDecoder.Frames)
        {
            BitmapMetadata btmd = (BitmapMetadata)frame.Metadata;
            duration += (ushort)btmd.GetQuery("/grctlext/Delay");
            _animation.KeyFrames.Add(new DiscreteInt32KeyFrame(_gifDecoder.Frames.IndexOf(frame)+1, KeyTime.FromTimeSpan(new TimeSpan(duration*100000))));
        }            
         _animation.RepeatBehavior = RepeatBehavior.Forever;
        this.Source = _gifDecoder.Frames[0];            
        _isInitialized = true;
    }

其他回答

这个小程序怎么样: 背后的代码:

public MainWindow()
{
  InitializeComponent();
  Files = Directory.GetFiles(@"I:\images");
  this.DataContext= this;
}
public string[] Files
{get;set;}

XAML:

<Window x:Class="PicViewer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="175" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <ListBox x:Name="lst" ItemsSource="{Binding Path=Files}"/>
        <MediaElement Grid.Column="1" LoadedBehavior="Play" Source="{Binding ElementName=lst, Path=SelectedItem}" Stretch="None"/>
    </Grid>
</Window>

我建议使用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));
}

添加到主响应,建议使用WpfAnimatedGif,你必须在最后添加以下行,如果你是交换图像与Gif,以确保动画实际执行:

ImageBehavior.SetRepeatBehavior(img, new RepeatBehavior(0));
ImageBehavior.SetRepeatBehavior(img, RepeatBehavior.Forever);

所以你的代码看起来像这样:

var image = new BitmapImage();
image.BeginInit();
image.UriSource = new Uri(fileName);
image.EndInit();
ImageBehavior.SetAnimatedSource(img, image);
ImageBehavior.SetRepeatBehavior(img, new RepeatBehavior(0));
ImageBehavior.SetRepeatBehavior(img, RepeatBehavior.Forever);

我也搜索了一下,在旧MSDN论坛的一个帖子里找到了几个不同的解决方案。(链接不再工作,所以我删除了它)

最简单的执行似乎是使用WinForms PictureBox控件,并像这样(从线程中更改了一些东西,大部分是相同的)。

添加对System.Windows的引用。窗体,WindowsFormsIntegration和系统。首先绘制你的项目。

<Window x:Class="GifExample.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
    xmlns:winForms="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
    Loaded="Window_Loaded" >
    <Grid>
        <wfi:WindowsFormsHost>
            <winForms:PictureBox x:Name="pictureBoxLoading">
            </winForms:PictureBox>
        </wfi:WindowsFormsHost>
    </Grid>
</Window >

然后在Window_Loaded处理程序中,你会设置pictureBoxLoading。将ImageLocation属性设置为要显示的图像文件路径。

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    pictureBoxLoading.ImageLocation = "../Images/mygif.gif";
}

在那个线程中提到了MediaElement控件,但也提到了它是一个相当笨重的控件,因此有许多替代方案,包括至少两个基于Image控件的自制控件,因此这是最简单的。

基本上与上面的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;
    }
}