在不违反MVVM模式的情况下拍摄mediaelement中的视频快照

时间:2015-07-10 07:06:37

标签: wpf mvvm mediaelement

我需要拍摄MediaElement中播放视频的快照。

以下链接说明了我们如何实现这一目标。

http://www.thomasclaudiushuber.com/blog/2008/04/06/take-snapshots-of-videos-with-wpf/

但是如何在不违反MVVM模式的情况下做到这一点。

2 个答案:

答案 0 :(得分:1)

我说链接中的代码并没有违反MVVM模式......它使用代码隐藏,这在MVVM中并不建议,但它并不违反。

话虽这么说,代码在可重用的UserControl或自定义Control中会更好,通过Event,Command或DependencyProperty返回快照,然后您可以将它绑定到ViewModel。

但是,这通常是一种良好实践的问题,而不是MVVM要求。

<UserControl x:Class="SnapShots.SnapShotMediaViewer"
    xmlns=http://schemas.microsoft.com/winfx/2006/xaml/...
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Name="MediaViewer">
  <StackPanel>
   <MediaElement x:Name="media" Stretch="Fill" Height="200" Width="300">
      <MediaElement.Triggers>
       <EventTrigger RoutedEvent="MediaElement.Loaded">
        <BeginStoryboard>
         <Storyboard>
          <MediaTimeline Source="thomasOnBoard.wmv"
                         RepeatBehavior="Forever"/>
         </Storyboard>
        </BeginStoryboard>
       </EventTrigger>
      </MediaElement.Triggers>
     </MediaElement>
     <Button Click="Button_Click" Content="Snapshot"/>
  </StackPanel>
</UserControl>

在代码隐藏中,例如,通过事件公开快照。或者,如果要在视图中完全避免代码隐藏或EventTriggers,请使用DependencyProperty。

public partial class SnapShotMediaViewer : UserControl
{
    public static readonly DependencyPropertyKey SnapshotPropertyKey =
        DependencyProperty.RegisterReadOnly("Snapshot", typeof(BitmapSource),
            typeof(SnapShotMediaViewer), new PropertyMetadata(null));

    public static readonly DependencyProperty SnapshotProperty =
        SnapshotPropertyKey.DependencyProperty;

    public BitmapSource Snapshot
    {
        get 
        {
            return (BitmapSource)GetValue(SnapshotProperty); 
        }
        private set
        {
            SetValue(SnapshotProperty, value);
        }
    }

    void Button_Click(object sender, RoutedEventArgs e)
    {
        Size dpi = new Size(96,96);
        RenderTargetBitmap bmp = 
            new RenderTargetBitmap(300, 200, 
            dpi.Width, dpi.Height, PixelFormats.Pbgra32);
        bmp.Render(media);

        Snapshot = bmp;
    }
}

然后只需将此控件添加到视图中,并创建一个绑定到Snapshot属性。

答案 1 :(得分:0)

<Button Command="{Binding TakeSnapshotCommand}" 
CommandParameter="{Binding ElementName=media}"/>

TakeSnapshotCommand是一个实现ICommand的类,如RelayCommand。另外你发送参数T,在这种情况下T是MediaElement,所以你将有以下声明。

private RelayCommand<MediaElement> _takeSnapshotCommand;
public RelayCommand<MediaElement> TakeSnapshotCommand
{
get{ return _takeSnapshotCommand ??(_takeSnapshotCommand = new RelayCommand<MediaElement>(YourMethodTakingMediaElementAsParameter));}
}