WPF (MVVM): Closing a view from a Viewmodel?

Does anyone come across a smart way to close a view in view mode using MVVM?

Maybe there is a way to use the binding to signal the closing of the window (s)?

I would really appreciate any input anyone has.

Basically, I have a loginView bound to loginViewModel in viewmodel (using command binding). I am testing to check if the login is successful, and if I basically load a new View (mainview) and attach its datacontext ...

but I still have the loginView shown, so I need to signal this for unloading.

I also hoped for a common solution, because I am sure that I will need to do similar things in other situations.

Any ideas?

+46
wpf mvvm wpftoolkit
Sep 27 '09 at 19:17
source share
11 answers

Edit: See my blog post for a more detailed explanation.

When I need to do this, I use the IRequestCloseViewModel interface that I created.

This interface contains only one event: RequestClose. This event is raised by the ViewModel (which inherits from the ViewModelBase class and implements IRequestCloseViewModel) when it wants to close the view associated with it.

In my application, all windows inherit from the abstract ApplicationWindow class. This abstract class is notified every time the DataContext is changed, and the handler checks to see if the DataContext supports IRequestCloseViewModel. If so, the event handler is configured to close the window when the event fires.

Alternatively, as Kent said, you can use a screen controller that handles this mecanism in the outer class.

+35
Sep 28 '09 at 11:04
source share

You don't know what MVVM structure you use, but most of them contain some kind of messaging / notification solution that is easy to register for messages that are sent. There is no reason to believe that your opinion could not be logged for a message such as "CloseWindowsBoundTo" and viewModel as the sender. Then, in your opinion, you can simply register for this message and compare your current data file with the sender. If they match, close the window.

Simple and keeps your reflection from your model.

Here is my approach using MVVM-light toolkit:

In ViewModel:

public void notifyWindowToClose() { Messenger.Default.Send<NotificationMessage>( new NotificationMessage(this, "CloseWindowsBoundToMe") ); } 

And in the view:

 Messenger.Default.Register<NotificationMessage>(this, (nm) => { if (nm.Notification == "CloseWindowsBoundToMe") { if (nm.Sender == this.DataContext) this.Close(); } }); 
+22
Jul 20 '10 at 19:36
source share

I used to use the behavior of the application on the dialog box, but it was easier for me to find the solution presented below. The following example shows an example of a close button in a window for simplicity.

pass the window as a parameter to the command.

in the xaml button to view:

 CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}" 

in the execute command, the method in the view model:

 if (parameter is System.Windows.Window) { (parameter as System.Windows.Window).Close(); } 
+9
Feb 27 '14 at 3:37
source share

Typically, you should use some kind of controller / presenter / service to control screen activation / deactivation. MVVM is not intended to become one of them, to fix them. You will need to combine it with other templates in any non-trivial application.

However, in some situations it makes sense to have a presentation model that governs the life cycle of children's vision models. For example, you might have an EditorViewModel that manages a collection of child view models — one for each document you are editing. In this case, simply adding / removing to / from this collection can lead to activation / deactivation. But this is not like how it fits your use case.

+8
Sep 27 '09 at 20:19
source share

http://adammills.wordpress.com/2009/07/01/window-close-from-xaml/

<Style.Triggers> <DataTrigger Binding="{Binding CloseSignal}" Value="true"> <Setter Property="Behaviours:WindowCloseBehaviour.Close" Value="true" /> </DataTrigger> </Style>

+7
Jul 19 '10 at 16:13
source share

You can make a command that joins the window, and when executed, closes the window. You can then bind this command to a property in your view model and execute the command when you want to close the window.

+4
Dec 14 '09 at 18:51
source share

I would use an ApplicationController that creates an instance of LoginViewModel and shows the LoginView. When the user goes to the login screen, ApplicationController closes the LoginView and displays the MainView using the MainViewModel.

How this can be done is shown in the application examples WPF Application Framework (WAF) .

+2
Oct 02 '09 at 17:54
source share

This answer shows another way to do this:

How to close ViewModel form?

It uses an attached property to bind the DialogResult window property to the ViewModel property. When DialogResult is set to true or false, the view closes.

+2
Aug 6 '10 at 17:03
source share

Just close the code in EventHandler and handle everything else in the view model, where you can use command binding.

+2
Jun 30 '12 at 18:37
source share

You can also do this using an event. Although you need as 3 lines of code in your view code (some MVVM purists don't like this);

In your view model, you create an event that the view can subscribe to:

  public event CloseEventHandler Closing; public delegate void CloseEventHandler(); private void RaiseClose() { if (Closing != null) Closing(); } 

In your view, you are subscribing to an event after your initializecomponent method, as shown below:

  public View { *//The event can be put in an interface to avoid direct dependence of the view on the viewmodel. So below becomes //ICloseView model = (ICloseView)this.DataContext;* ProgressWindowViewModel model = (ProgressWindowViewModel)this.DataContext; model.Closing += Model_Closing; } private void Model_Closing() { this.Close(); } 

You simply call RaiseClose () when you are ready to close the view from the ViewModel.

You can even use this method to send a message to a view from view mode.

The event can be placed in the interface to avoid direct dependence of the view on the viewmodel.

+1
Aug 11 '17 at 11:38 on
source share

To close the view from the viewmodel, I used the Galasoft MVVM Light Toolkit, which you can download here: http://www.mvvmlight.net/

  • create the class as follows: public class ClosingRequested: MessageBase {}

  • add this to the view constructor: Messenger.Default.Register (this, vm, msg => Close ());

  • call this to close the window: Messenger.Default.Send (new ClosingRequested (), this);

0
Jul 28 '15 at 15:58
source share



All Articles