如何使用MVVM模式从ViewModel调用View中的函数(与UIElements一起使用)

时间:2012-09-09 15:38:10

标签: mvvm view viewmodel screenshot mvvm-light

我正在使用MVVM Light Toolkit,在我的View中,我有一个功能,它截取屏幕截图并返回该屏幕截图的字节数组。由于截取屏幕截图(使用UIElement s)与视图而非ViewModel相关。

byte[] TakeScreenShot(Canvas sourceUiElement)    

我需要在ViewModel中获取函数的返回值,但我无法想出一个正确的方法。

另一方面,如果我想将此函数移动到我的ViewModel,我需要在视图中访问该元素,但不能在我的ViewModel中引用View(可能作为参数或Command的某些内容? )

2 个答案:

答案 0 :(得分:1)

由于此问题被标记为MvvmLight,因此这是一个MvvmLight Toolkit答案。使用所述工具包的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));
});

在您的视图模型中,注册ScreenshotTakenMessage,如下所示:

Messenger.Default.Register<ScreenshotTakenMessage>(this, (msg) =>
{
    byte[] bytes = msg.Content.
    //do something with your bytes
});

现在,您可以随时通过从应用程序中的任何位置调用以下内容(即视图模型,视图,帮助程序等)来拍摄屏幕截图:

Messenger.Default.Send(new TakeScreenshotMessage());

答案 1 :(得分:0)

我会将TakeScreenShot绑定到按钮的click事件或后面代码中的某些内容,例如在ViewModel上有一个名为 Snapshot 的属性,并且在click事件中,您将获得该字节[]数组,将其分配给ViewModel的属性快照,就像在后面的代码中一样。

public void ButtonOnClick(object sender, EventArgs e)
{
    var myViewModel = this.DataContext;
    myViewModel.Snapshot = this.TakeScreenShot(someCanvas);
}

取决于你对MVVM的严格程度,有些人可能不同意,我认为你的视图完全有效引用你的viewmodel,也就是你必须知道你绑定的上下文,但不是相反。这就像手动绑定我一样。