2014-04-13 32 views
0

我已将媒体元素添加到播放gif文件的WPF窗口。但我不确定如何在几秒钟后停止GIF播放。如何在设定的时间后致电停止MediaElement?

在我当前的实现中,gif会指导用户如何在窗口加载时执行动作,但我不希望gif在循环中播放,我希望能够在停止gif之后停止gif几秒钟。

是否有可能通过媒体元素实现这一点?

private void Window_Loaded(object sender, RoutedEventArgs e) 
{ 
     // set the phrases to listen for and start listening 
     listener.Phrases = PhrasesTextBox.Text; 
     listener.StartListening(); 

     gifMediaElement.Play(); 

} 

回答

1

如果您想继续使用MediaElement类型,一种方法是使用DispatcherTimer。您可以将其设置为在特定秒数内打勾并关闭定时器和MediaElement。例如:

DispatcherTimer timer = new DispatcherTimer(); 
private void Window_Loaded(object sender, RoutedEventArgs e) 
{ 
    //... 
    gifMediaElement.Play(); 
    timer.Interval = TimeSpan.FromSeconds(5); 
    timer.Start(); 
    timer.Tick += (o, args) => 
    { 
     timer.Stop(); 
     gifMediaElement.Stop(); 
    }; 
    //... 
2

尝试使用AnimatedGIFControl

在WPF的MediaElement可以显示动画GIF图像有一些不太理想的局限性:

  1. 来源属性必须以绝对路径进行设置;
  2. 默认情况下不支持播放功能;
  3. 透明像素显示为黑色。

下面是例如使用AnimatedGIFControl的:

XAML

<Window x:Class="CSWPFAnimatedGIF.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:CSWPFAnimatedGIF" 
     Title="Animated GIF" Height="300" Width="300"> 

    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition/> 
      <RowDefinition/> 
     </Grid.RowDefinitions> 

     <local:AnimatedGIFControl x:Name="GIFCtrl"/> 

     <Button x:Name="btnStart" Width="70" Height="30" Margin="50" 
       HorizontalAlignment="Left" Grid.Row="1" Click="btnStart_Click">Start</Button> 

     <Button x:Name="btnStop" Width="70" Height="30" Margin="50" 
       HorizontalAlignment="Right" Grid.Row="1" Click="btnStop_Click">Stop</Button>   
    </Grid> 
</Window> 

Code-behind

public class AnimatedGIFControl : System.Windows.Controls.Image 
{ 
    private Bitmap _bitmap; // Local bitmap member to cache image resource 
    private BitmapSource _bitmapSource; 
    public delegate void FrameUpdatedEventHandler(); 


    /// <summary> 
    /// Delete local bitmap resource 
    /// Reference: http://msdn.microsoft.com/en-us/library/dd183539(VS.85).aspx 
    /// </summary> 
    [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    static extern bool DeleteObject(IntPtr hObject); 

    /// <summary> 
    /// Override the OnInitialized method 
    /// </summary> 
    protected override void OnInitialized(EventArgs e) 
    { 
     base.OnInitialized(e); 
     this.Loaded += new RoutedEventHandler(AnimatedGIFControl_Loaded); 
     this.Unloaded += new RoutedEventHandler(AnimatedGIFControl_Unloaded);   
    } 

    /// <summary> 
    /// Load the embedded image for the Image.Source 
    /// </summary> 

    void AnimatedGIFControl_Loaded(object sender, RoutedEventArgs e) 
    { 
     // Get GIF image from Resources 
     if (Properties.Resources.ProgressIndicator != null) 
     { 
      _bitmap = Properties.Resources.ProgressIndicator; 
      Width = _bitmap.Width; 
      Height = _bitmap.Height; 

      _bitmapSource = GetBitmapSource(); 
      Source = _bitmapSource; 
     }    
    } 

    /// <summary> 
    /// Close the FileStream to unlock the GIF file 
    /// </summary> 
    private void AnimatedGIFControl_Unloaded(object sender, RoutedEventArgs e) 
    { 
     StopAnimate(); 
    } 

    /// <summary> 
    /// Start animation 
    /// </summary> 
    public void StartAnimate() 
    { 
     ImageAnimator.Animate(_bitmap, OnFrameChanged); 
    } 

    /// <summary> 
    /// Stop animation 
    /// </summary> 
    public void StopAnimate() 
    { 
     ImageAnimator.StopAnimate(_bitmap, OnFrameChanged); 
    } 

    /// <summary> 
    /// Event handler for the frame changed 
    /// </summary> 
    private void OnFrameChanged(object sender, EventArgs e) 
    { 
     Dispatcher.BeginInvoke(DispatcherPriority.Normal, 
           new FrameUpdatedEventHandler(FrameUpdatedCallback)); 
    } 

    private void FrameUpdatedCallback() 
    { 
     ImageAnimator.UpdateFrames(); 

     if (_bitmapSource != null) 
      _bitmapSource.Freeze(); 

     // Convert the bitmap to BitmapSource that can be display in WPF Visual Tree 
     _bitmapSource = GetBitmapSource(); 
     Source = _bitmapSource; 
     InvalidateVisual(); 
    } 

    private BitmapSource GetBitmapSource() 
    { 
     IntPtr handle = IntPtr.Zero;     

     try 
     { 
      handle = _bitmap.GetHbitmap(); 
      _bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(
       handle, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); 
     } 
     finally 
     { 
      if (handle != IntPtr.Zero) 
       DeleteObject(handle); 
     } 

     return _bitmapSource; 
    } 
} 

Code Logic

  1. 使用ImageAnimator到动画有基于时间的帧GIF图像。
  2. 使用InvalidateVisual方法在另一个线程中呈现每帧GIF图像。
  3. Image控制衍生出来,以便使其易于用作图像控件。
  4. 配置转储资源以确保效率。
相关问题