tags:

views:

84

answers:

2

I'm creating a basic database application in WPF, and I have started using the MVVM pattern.

I have a dialog that asks the user to select an item from a ListBox and click "OK." After that, I take the item the user clicked from a property in the view model and pass it into another dialog. But if the user clicks "Cancel," I set that value to null, and the action is canceled: I don't open the next dialog and return to the main screen. Example:

public class SelectEquipmentViewModel : WorkspaceViewModel
{
    private bool _selected;

    public Equipment SelectedEquipment
    {
        // Item selected by the user
    }

    // Action for "SelectCommand," which is attached to
    // the "Select" button in the view
    public void ExecuteSelect()
    {
        _selected = true;

        // Fires a RequestClose event in WorkspaceViewModel,
        // which is attached to the view's Close method
        RequestClose();
    }

    public override void RequestClose()
    {
        if (!_selected)
        {
            // The user clicked "Cancel"
            SelectedEquipment = null;
        }

        base.RequestClose();
    }
}

This has been working great, but the problem comes if the user clicks the red "X" close button in the window's control box. The RequestClose method never gets invoked, and the selected item isn't set to null, which is bad.

I've considered attaching the view model to the Closing event of the view, but I feel this could get messy if I start creating handlers for all these events.

What would be the "preferred" way of handling this situation?

Thanks.

+2  A: 

I think that using the EventToCommand behavior to wire up the Window object's Closing event to a new ExecuteCancel command is pretty clean.

public void ExecuteCancel() 
{ 
    _selected = false; 

    // Fires a RequestClose event in WorkspaceViewModel, 
    // which is attached to the view's Close method 
    RequestClose(); 
}

Where do you think this will get messy? If you add a Cancel button, it could use the same ExecuteCancel bits...

Chris Koenig
As far as I know, this is the best way to do this in M-V-VM. There are some situations when you still have to put some logic in the code-behind class, as much as you hate doing that with M-V-VM.
Dave White
This was exactly what I needed, thank you very much!
nasufara
A: 

Behaviors are what you want to use to execute a command when the user presses the "X" button on window using MVVM. Check out Reed Copsey's blog here: http://reedcopsey.com/2009/10/09/using-behaviors-to-allow-the-viewmodel-to-manage-view-lifetime-in-m-v-vm/

You can download a sample application here...

I use this method all the time to allow the ViewModel manage the life of the view.

Brent