我在使用MVVMLight拍摄屏幕截图时遇到了问题,并创建了以下可怕的解决方法。也许你可以帮助我在不使用Code-behind的情况下做得更好。
我的应用程序的MainWindow有一个菜单选项“Take screenshot”。它还有一个TabControl,带有动态创建的Tabs。
<DataTemplate DataType="{x:Type vm:OverviewViewModel}">
<local:OverviewView/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:MzViewModel}">
<local:MzView/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:TabViewModel2}">
<local:TabView/>
</DataTemplate>
“TakeScreenshot”命令使用MVVMLight向TabViewModel发送消息:
public ICommand SaveImage { get { return new RelayCommand(SaveImageExecute); } }
private void SaveImageExecute()
{
MessengerInstance.Send(Index, "Picture");
}
在TabViewModel中,我收到消息并调用一个函数:
MessengerInstance.Register<int>(this, "Picture", TakePicture);
void TakePicture(int tabnumber)
{
if (tabnumber == _tabNumber)
{
_screenshot = true;
ScreenshotParam++;
}
}
ScreenshotParam绑定到View中的按钮的Width属性并触发SizeChanged-Event。这会触发ViewModel中的ICommand,并为ViewModel提供使用CommandParameter获取屏幕截图所需的UserControl。
<Button Width="{Binding ScreenshotParam}" Visibility="Hidden" Height="0">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SizeChanged">
<cmd:EventToCommand Command="{Binding Screenshot}" CommandParameter="{Binding ElementName=UserControl}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
最后,我可以在ViewModel中获取我的屏幕截图:
public ICommand Screenshot { get { return new RelayCommand<object>(OnScreenshot); } }
private void OnScreenshot(object obj)
{
UserControl uc = (UserControl)obj;
RenderTargetBitmap renderTargetBitmap =
new RenderTargetBitmap((int)uc.ActualWidth, (int)uc.ActualHeight, 96, 96, PixelFormats.Pbgra32);
renderTargetBitmap.Render(uc);
PngBitmapEncoder pngImage = new PngBitmapEncoder();
pngImage.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
....
}