打开WPF窗口MVVM并关闭它

时间:2012-11-26 12:53:33

标签: c# wpf mvvm visual-studio-2012

  

可能重复:
  WPF MVVM Newbie - how should the ViewModel close the form?

我搜索过stackoverflow,我不认为给出的答案适用于我的,或者我无法理解如何应用它们。

我有一个标准的MVVM WPF应用程序。 MVVM部分包括一个RelayCommand类和一个ViewModelBase类以及一个扩展ViewModelBase的WorkspaceViewModel类。

我有两个窗口,MainWindow和CustomMessageBox窗口(实际上为用户提供了一个问题和两个答案)。我在MainWindow中使用此代码打开CustomMessageBox(第二个窗口):

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;
        }
    }

启动CustomMessageBox后,我无法使用CloseCommand关闭它。当我尝试调试CustomMessageBox的加载时,似乎所有的ICommands在我按下之前都被触发了?

WorkspaceViewModel具有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]

有没有人有任何想法?我遗漏了什么至关重要的东西吗?

谢谢,

2 个答案:

答案 0 :(得分:1)

当我需要完成此操作时,我从Command.Execute逻辑调用以下代码行:

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

我希望这会有所帮助。

答案 1 :(得分:1)

我实际上没有将任何方法附加到事件处理程序,所以当调用事件处理程序时,什么都没有做,因为代码到了死胡同,所以我更改了代码并附加了窗口的Close方法到ViewModel的事件处理程序:

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

这是完整的代码:

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;
    }
}

感谢大家帮助我得到答案,这只是为了澄清我的问题。

感谢。