WPF& MVVM - 从Child控件中关闭窗口

时间:2015-02-09 16:28:32

标签: c# wpf mvvm controls

我需要根据在窗口中显示的控件中触发的单击命令从ViewModel关闭模式窗口。

所以,我有MainViewModel,JimViewModel,JimWindow和JimControl。 MainViewModel创建一个JimWindow并将其DataContext设置为JimViewModel。 JimWindow包含JimControl,其中包含一个按钮。单击此按钮时,我想触发一个以某种方式关闭JimWindow的命令。

我已经看到一些问题可以解决这个问题,关于从实际窗口关闭Window(通过将Window的实例传递给ViewModel上的命令),但它没有转化为我想要的做。

我没有使用框架,所以我没有方便的信使来帮助我。有人可以帮忙吗?是否以某种方式引用控件中父窗口的名称?

2 个答案:

答案 0 :(得分:1)

MainViewModel不应该创建窗口,至少不能直接创建窗口。虚拟机应该只创建虚拟机。窗口是视图世界的一部分。

如果您需要在窗口中托管JimVM,那么最好在界面后面抽象某种WindowServiceMainVM然后只创建JimVM并将其提供给窗口服务以在窗口中托管

一旦你将windows位解耦成一个单独的服务,那么你就可以在那里做所有狡猾的窗口。我会JimVM展示CloseCommandClosed事件。您可以将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));
}