使用MVVM时退出应用程序或关闭控件 [英] Exiting an App or Closing a Control When Using MVVM

查看:103
本文介绍了使用MVVM时退出应用程序或关闭控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的WPF应用程序中,我使用的是没有IoC的ViewModelLocator.我从我自己的按钮上调用了MVVM-Light框架提供的静态ViewModelLocator.Cleanup()方法,该按钮绑定到关闭窗口命令".该命令调用静态ViewModelLocator.Cleanup(),该静态ViewModelLocator.Cleanup()在我的MainWindowViewModel实例上调用实例Cleanup()方法.然后,实例Cleanup()方法将MainWindow绑定其DataContext的属性设置为null.该属性上的setter引发一个PropertyChanged事件.奇怪的是,将此属性设置为null不会导致窗口关闭.

In my WPF application, I am using the ViewModelLocator without IoC. I am calling the static ViewModelLocator.Cleanup() method provided by the MVVM-Light framework from my own button which is tied to a "close window command". This Command calls the static ViewModelLocator.Cleanup(), which calls an instance Cleanup() method on my MainWindowViewModel instance. The instance Cleanup() method then sets the property to which the MainWindow binds its DataContext, to null. The setter on the property raises a PropertyChanged event. Curiously, setting this property to null does not cause the window to close.

我试图理解为什么会这样?如果将MainWindow的DataContext设置为null,那应该与Window.Close()不同吗?就我而言,Window及其所有元素保留在屏幕上.但是,如果我尝试进一步的操作,则会得到空指针异常,表明DataContext绑定属性确实设置为null;这也已在调试器中得到确认.

I am trying to understand why this is the case? If I set the MainWindow's DataContext to null, should that not be the same as Window.Close()? In my case, the Window and all of its elements remain on the screen. However, if I attempt further actions, I get null pointer exceptions, indicating the DataContext binding Property has indeed been set to null; this has also been confirmed in the debugger.

我通过钩挂Application.Exit事件并在事件处理程序中发出Window.Close()来创建变通方法,以便创建自己的关闭窗口"按钮(即为我自己的Button创建相同的功能/命令,方法是单击窗口右上角的X按钮).由于直接从MVVM调用UI元素(即Window实例)不是MVVM友好的,因此我使用了 ViewService 来实现Window.Close()功能,以保持变通方法MVVM友好.我是ViewService习惯用法(或模式)的忠实拥护者,但我认为这里没有必要这样做;除此之外,我可以看到退出应用程序是一种特殊情况,也许应该与应用程序生命周期挂钩,.Net似乎只允许通过发出Window.Close()方法来退出WPF应用程序.

I have created a workaround by hooking the Application.Exit event and issuing a Window.Close() in the event handler in order to create my own "Close Window" button (ie, to create same functionality for my own Button / Command as clicking the X button in the upper right of a Window). Since calling a UI element (ie, the Window instance) from MVVM directly is not MVVM friendly, I used a ViewService to implement the Window.Close() functionality in order to keep the workaround MVVM friendly. I am a big fan of the ViewService idiom (or pattern), but I just don't think it should be necessary here; except, I could see how exiting the app is a special case that perhaps should tie-in with the application lifecycle, and .Net seems to only allow exiting a WPF app by issuing the Window.Close() method.

对此表示感谢.

推荐答案

除了在与flq的评论讨论中提出的问题之外,我相信我已经找到了原始问题的答案.

I believe I have found the answer to my original question, in addition to the one raised in my comments discussion with flq.

首先,对原始问题的回答是,关闭窗口的正确方法是按照我在上述解决方法"中所做的工作.关闭应用程序是一个由View启动的过程,因为Window控件具有执行操作的位.当然,您可以挂钩Application.Exit事件,以便可以对ViewModel执行清理,提示用户保存数据,等等.

First, the answer to the original question is that the proper way to close the Window is along the lines of what I did in my described "workaround". Closing an app is a View-initiated process, as it is the Window control that has the bits for how to do it. You can of course hook the Application.Exit event so that you can perform cleanup on your ViewModels, prompt the user to save data, etc..

在与flq进行了一些有趣的讨论之后,我提出的问题是,如果我不只是为了将View和ViewModel资源释放而将控件的DataContext(即ViewModel)设置为null,我应该怎么做? ?

The question raised by me after some interesting discussion with flq is, if I don't just set a control's DataContext (ie, ViewModel) to null in order to release the View and ViewModel resources, how should I do it?

可以在此处找到有趣的讨论,其中包含一些细微差别.您找到了父控件,并从其子级"列表中删除了要关闭的控件.请注意,这是另一种具有不同目标的技术,而不只是通过将可见性"属性设置为折叠"来使控件不可见.在下面的示例中,"this"是要删除的控件(即"Closed"):

An interesting discussion with some nuances can be found here, but the basic answer is that you find the parent control and remove the control you want to close from its Children list. Note, this is a different technique with a different goal than just making the control not visible by setting is Visibility property to Collapsed. In the following example, "this" is the control to be removed (ie, "Closed"):

Panel p = (Panel) this.Parent;
p.Children.Remove(this);

我不确定您是否仍然需要将子级(即"this")设置为null来重新声明其资源,或者,如果只是将其从可视树中删除,则会导致WPF重新声明其资源.资源;上面的链接讨论没有提及.如原始讨论所述,可以通过将其挂接到某些事件来补充上述技术. ,或使用其他特定于应用程序的逻辑.

I am not sure if you still need to then set the child (ie, "this") to null to re-claim its resources, or, if just removing it from the visual tree will cause WPF to re-claim the resources; the above linked discussion makes no mention. As mentioned in the original discussion, the above technique can be supplemented by hooking it to certain events, or using other application specific logic.

这篇关于使用MVVM时退出应用程序或关闭控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆