1

Possible Duplicate:
WPF MVVM Newbie - how should the ViewModel close the form?

I've searched around stackoverflow and I don't think the answers given apply to mine or I can't fathom out how to apply them.

I have a bog standard MVVM WPF application. The MVVM parts consist of a RelayCommand class and a ViewModelBase class and a WorkspaceViewModel class extending ViewModelBase.

I have two windows, the MainWindow and the CustomMessageBox window (which actually provides a the user with a question and two answers). I use this code in MainWindow to open the CustomMessageBox (second window):

public ICommand BrowseFileFolderCommand
    {
        get
        {
            if (_browseFileFolderCommand == null)
            {
                _browseFileFolderCommand = new RelayCommand(o =>
                    {
                        var messageViewModel = new MessageBoxViewModel("Add a Folder or File", "What do you wish to add, folder or file?", "Folder", "File");
                        var choice = new CustomMessageBox()
                        {
                            DataContext = messageViewModel
                        };
                        choice.ShowDialog();

                        if (messageViewModel.CustomMessageBoxDialogResult == DialogResult.Yes)
                        {
                            switch (messageViewModel.ChosenEntity)
                            {
                                case SelectedAnswer.Answer1:
                                    // Get folder shizz
                                    break;
                                case SelectedAnswer.Answer2:
                                    // Get file shizz
                                    break;
                                default:
                                    break;
                            }
                        }
                    }, null);
            }
            return _browseFileFolderCommand;
        }
    }

Once the CustomMessageBox has been launched I cannot close it with the CloseCommand. When I try and debug the loading of CustomMessageBox, it's seems all the ICommands are fired off before I press anything?

The WorkspaceViewModel has the CloseCommand:

 #region CloseCommand

    /// <summary>
    /// Returns the command that, when invoked, attempts
    /// to remove this workspace from the user interface.
    /// </summary>
    public ICommand CloseCommand
    {
        get
        {
            if (_closeCommand == null)
                _closeCommand = new RelayCommand(param => this.OnRequestClose());

            return _closeCommand;
        }
    }

    #endregion // CloseCommand

    #region RequestClose [event]

    /// <summary>
    /// Raised when this workspace should be removed from the UI.
    /// </summary>
    public event EventHandler RequestClose;

    void OnRequestClose()
    {
        EventHandler handler = this.RequestClose;
        if (handler != null)
            handler(this, EventArgs.Empty);
    }

    #endregion // RequestClose [event]

Has anyone got any ideas? Have I left out anything crucial?

Thanks,

Community
  • 1
  • 1
Callum Linington
  • 14,213
  • 12
  • 75
  • 154

2 Answers2

1

When I need to accomplish this, I call the following line of code from my Command.Execute logic:

App.Current.Windows.Cast<Window>().Where(win => win is CustomMessageBox).FirstOrDefault().Close();

I hope this helps.

XamlZealot
  • 693
  • 5
  • 12
  • So replace my CloseCommand logic with your line? – Callum Linington Nov 26 '12 at 13:43
  • Well I don't know if you have other logic to execute when your command is fired, so whether you replace your existing logic entirely, or simply include that line in there is up to you. However, that line of code will close the Window from anywhere in the application (even the ViewModel), so you don't have to raise/handle an event on the UI side (the View) in order to close the desired Window. – XamlZealot Nov 26 '12 at 13:49
1

I hadn't actually attached any Method to the Event Handler, so when the Event Handler was called, nothing did anything because the code came to a dead end, so I changed the code and I attached the Close method of the Window to the Event Handler of the ViewModel:

messageViewModel.RequestClose += (s, e) => choice.Close();

Here's the full code:

public ICommand BrowseFileFolderCommand
{
    get
    {
        if (_browseFileFolderCommand == null)
        {
            _browseFileFolderCommand = new RelayCommand(() =>
                {
                    var messageViewModel = new MessageBoxViewModel("Add a Folder or File", "What do you wish to add, folder or file?", "Folder", "File");
                    var choice = new CustomMessageBox()
                    {
                        DataContext = messageViewModel
                    };
                    // Added this line
                    messageViewModel.RequestClose += (s, e) => choice.Close();
                    choice.ShowDialog();

                    if (messageViewModel.CustomMessageBoxDialogResult == DialogResult.Yes)
                    {
                        switch (messageViewModel.ChosenEntity)
                        {
                            case SelectedAnswer.Answer1:
                                // Get folder shizz
                                break;
                            case SelectedAnswer.Answer2:
                                // Get file shizz
                                break;
                            default:
                                break;
                        }
                    }
                }, null);
        }
        return _browseFileFolderCommand;
    }
}

Thanks everyone to help me get the answer, this is just to clarify against my problem in particular.

Thanks.

Xander Luciano
  • 3,753
  • 7
  • 32
  • 53
Callum Linington
  • 14,213
  • 12
  • 75
  • 154