如何在WPF中从ViewModel设置窗口作为所有者

时间:2016-11-24 12:27:11

标签: c# wpf mvvm

如何将窗口设置为从ViewModel声明,初始化和打开的所有者?

以下是代码:

public class ViewModel : INotifyPropertyChanged

{
  // declaration
  static nextWindow nw;
  ...

  public ICommand OpenNextWindow { get { return new RelayCommand(OpenNextWindowExecute, CanOpenNextWindowExecute); } }

  bool CanOpenNextWindowExecute(object parameter)
  {
      return true;
  }

  void OpenNextWindowExecute(object parameter)
  {
      nw = new nextWindow();
      nw.WindowStartupLocation = WindowStartupLocation.CenterScreen;
      // Set this window as owner before showing it...
      nw.Show();
  }
 }

在nextWindow的代码隐藏文件中,我可以使用以下代码将nextWindow设置为所有者:

nw.Owner = this;

如何从viewmodel中实现它?

3 个答案:

答案 0 :(得分:4)

老实说,我不会做任何与在ViewModel中显示窗口相关的事情。你可以做的是,发送一条消息(例如使用MVVMLight的Messenger服务)到View,你可以在那里做show并设置所有者shinanigaz

答案 1 :(得分:2)

MVVM背后的全部理念是,您希望在视图和业务逻辑之间实现清晰的分离,从而实现更好的维护,可伸缩性,测试等。因此,您的视图模型应始终不会意识到任何视图的存在。

因此,使用一个信使服务,视图或某些视图处理程序可以监听,然后决定是否要处理该消息。因此,让viewhandler决定下一个要调用的其他视图或要显示的消息框。

有许多选择,但正如@Oyiwai所说,MVVMLight的Messenger服务很快就易于使用。

在您的软件包管理器控制台中运行install-package MvvmLightLibs。 MvvmLightLibs还有一个额外的好处,它已经有一个INotifyPropertyChanged的实现,我看到你实现了。

请注意,这是一个快速示例。我不推荐使用case语句,因为我在这里使用硬编码查看名称。

创建一个WindowMessage类..

public class RaiseWindowMessage
{
    public string WindowName { get; set; }
    public bool ShowAsDialog { get; set; }
}

在您的viewmodel

public class ViewModel : ViewModelBase
{
    public RelayCommand<string> RaiseWindow => new RelayCommand<string>(raiseWindow, canRaiseWindow);

    private bool canRaiseWindow(string nextWindowName)
    {
        // some logic
        return true;
    }

    private void raiseWindow(string nextWindowName)
    {
        RaiseWindowMessage message = new RaiseWindowMessage();
        message.WindowName = nextWindowName;
        message.ShowAsDialog = true;

        MessengerInstance.Send<RaiseWindowMessage>(message);
    }
}

在您的视图中或最好在某个视图处理程序类中。

public class ViewHandler
{
    public ViewHandler()
    {
        Messenger.Default.Register<RaiseWindowMessage>(this, raiseNextWindow);
    }        

    private void raiseNextWindow(RaiseWindowMessage obj)
    {
        // determine which window to raise and show it
        switch (obj.WindowName)
        {
            case "NextWindow":
                NextWindow view = new NextWindow();
                if (obj.ShowAsDialog)
                    view.ShowDialog();
                else
                    view.Show();
                break;
            // some other case here...
            default:
                break;
        }
    }
}

答案 2 :(得分:-3)

nw.Owner = Application.Current.MainWindow;