我需要拍摄MediaElement中播放视频的快照。
以下链接说明了我们如何实现这一目标。
http://www.thomasclaudiushuber.com/blog/2008/04/06/take-snapshots-of-videos-with-wpf/
但是如何在不违反MVVM模式的情况下做到这一点。
答案 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));}
}