我使用的是MVVM Light Toolkit,在我的View中,我有一个函数可以获取屏幕截图并返回该屏幕截图的字节数组。由于截屏(使用UIElement
s)与视图而非ViewModel有关。
byte[] TakeScreenShot(Canvas sourceUiElement)
我需要在ViewModel中获得函数的返回值,但我无法想出正确的方法。
另一方面,如果我想把这个函数移到我的ViewModel中,我需要访问视图中的那个元素,但不引用ViewModel中的view(可能是作为参数或Command
?的东西)
由于此问题被标记为MvvmLight,因此下面是MvvmLightToolkit的答案。使用上述工具箱的Messenger
类。只需在应用程序中的某个位置定义以下消息类:
public class TakeScreenshotMessage : MessageBase { }
public class ScreenshotTakenMessage : GenericMessage<byte[]>
{
public ScreenshotTakenMessage (byte[]content) : base(content) { }
public ScreenshotTakenMessage (object sender, byte[]content) : base(sender, content) { }
public ScreenshotTakenMessage (object sender, object target, byte[]content) : base(sender, target, content) { }
}
在代码隐藏的构造函数中,注册TakeScreenshotMessage,如下所示:
Messenger.Default.Register<TakeScreenshotMessage>(this, (msg) =>
{
byte[] bytes = this.TakeScreenShot(someCanvas);
Messenger.Default.Send(new ScreenshotTakenMessage(bytes));
});
在您的视图模型中,注册ScreenshotTakeMessage,如下所示:
Messenger.Default.Register<ScreenshotTakenMessage>(this, (msg) =>
{
byte[] bytes = msg.Content.
//do something with your bytes
});
现在,只需从应用程序中的任何位置调用以下命令(即视图模型、视图、辅助类等),您就可以随时进行屏幕截图:
Messenger.Default.Send(new TakeScreenshotMessage());
我会将TakeScreenShot与按钮的点击事件或代码后面的东西绑定,在ViewModel上有一个名为Snapshot的属性,例如,在点击事件中,您获得byte[]数组,将其分配给ViewModel的属性Snapshot,就像代码后面一样。
public void ButtonOnClick(object sender, EventArgs e)
{
var myViewModel = this.DataContext;
myViewModel.Snapshot = this.TakeScreenShot(someCanvas);
}
取决于你对MVVM的严格程度,有些人可能不同意,我认为你的视图引用你的视图模型是完全有效的,也就是说,你必须知道你绑定到的上下文,但不能反过来。这就像手动绑定到我。