我需要根据在窗口中显示的控件中触发的单击命令从ViewModel关闭模式窗口。
所以,我有MainViewModel,JimViewModel,JimWindow和JimControl。 MainViewModel创建一个JimWindow并将其DataContext设置为JimViewModel。 JimWindow包含JimControl,其中包含一个按钮。单击此按钮时,我想触发一个以某种方式关闭JimWindow的命令。
我已经看到一些问题可以解决这个问题,关于从实际窗口关闭Window(通过将Window的实例传递给ViewModel上的命令),但它没有转化为我想要的做。
我没有使用框架,所以我没有方便的信使来帮助我。有人可以帮忙吗?是否以某种方式引用控件中父窗口的名称?
答案 0 :(得分:1)
MainViewModel
不应该创建窗口,至少不能直接创建窗口。虚拟机应该只创建虚拟机。窗口是视图世界的一部分。
如果您需要在窗口中托管JimVM
,那么最好在界面后面抽象某种WindowService
。 MainVM
然后只创建JimVM
并将其提供给窗口服务以在窗口中托管
一旦你将windows位解耦成一个单独的服务,那么你就可以在那里做所有狡猾的窗口。我会JimVM
展示CloseCommand
和Closed
事件。您可以将JimControl
按钮绑定到CloseCommand
,Windows服务可以订阅Close
事件,并在触发时拆除窗口。
这使视图和VM内容完全分开。唯一知道如何将两者粘合在一起的是窗口管理器。
答案 1 :(得分:0)
虽然ViewModel
创建View
的想法听起来有点落后,但您可以使用消息传递,例如TinyMessenger附带的MVVMLight或Messenger。
然后,您可以在View / ViewModel中注册一条消息,然后从任何地方发送消息。使用MVVMLight的一个非常简单的例子可能是:
// custom message
public class CloseMessage : MessageBase
{
public CloseMessage(object sender)
:base(sender)
{}
}
// main view registers for a message
public partial class MainWindow : Window
{
public MainWindow()
{
Messenger.Default.Register<CloseMessage>(this, message =>
{
// do teh stuff
});
}
...
}
// command bound to close button sends the message
private void YourCloseMainViewCommand()
{
Messenger.Default.Send(new CloseMessage(this));
}