【问题标题】:ShowDialog() behind the parent window父窗口后面的 ShowDialog()
【发布时间】:2012-03-24 21:53:45
【问题描述】:

我正在使用 ShowDialog()WindowStyle = WindowStyle.SingleBorderWindow; 在我的 WPF (MVVM) 应用程序中打开一个模式窗口,但它允许我使用 Windows 任务栏 (Windows 7) 导航到父窗口。

我在这里找到了答案:WPF and ShowDialog(),但它不适合我,因为我不需要“始终位于顶部”的工具窗口。

提前致谢

【问题讨论】:

    标签: wpf showdialog


    【解决方案1】:

    尝试设置对话框的Owner 属性。应该可以的。

    Window dialog = new Window();
    dialog.Owner = mainWindow;
    dialog.ShowDialog();
    

    编辑: 我在使用 MVVM 时遇到了类似的问题。您可以使用委托解决此问题。

    public class MainWindowViewModel
    {
        public delegate void ShowDialogDelegate(string message);
        public ShowDialogDelegate ShowDialogCallback;
    
        public void Action()
        {
            // here you want to show the dialog
            ShowDialogDelegate callback = ShowDialogCallback;
            if(callback != null)
            {
                callback("Message");
            }
        }
    }
    
    public class MainWindow
    {
        public MainWindow()
        {
            // initialize the ViewModel
            MainWindowViewModel viewModel = new MainWindowViewModel();
            viewModel.ShowDialogCallback += ShowDialog;
            DataContext = viewModel;
        }
    
        private void ShowDialog(string message)
        {
            // show the dialog
        }
    }
    

    【讨论】:

    • 谢谢,这个主意不错。此时唯一的问题是在 ViewModel 中我没有 View 的信息。我尝试了App.Current.MainWindow,它可以工作,但不是最好的解决方案。也许我应该重新考虑我的 MVVM 模式的结构。
    • 我为 MVVM 问题添加了一个可能的解决方案。
    • @Oszkar 我使用了Application.Current.MainWindow(应用程序而不是应用程序),因为它是静态的——我猜——它工作得很好,不会让 MVVM 感到痛苦。
    【解决方案2】:

    我遇到了这个问题,但是当从视图模型打开窗口时,我没有对当前窗口的引用。为了绕过它,我使用了以下代码:

    var myWindow = new MyWindowType();
    myWindow.Owner = Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive);
    

    您可以使用:myWindow.Owner = Application.Current.MainWindow;

    但是,如果您像这样打开三个窗口,则此方法会导致问题:

    MainWindow
       |
       -----> ChildWindow1
    
                   |
                   ----->  ChildWindow2
    

    然后设置 ChildWindow2.Owner = Application.Current.MainWindow 会将窗口的所有者设置为其祖父窗口,而不是父窗口。

    【讨论】:

      【解决方案3】:

      当父窗口创建(并显示)子窗口时,您需要设置所有者。

      public partial class MainWindow : Window
      {
      
          private void openChild()
          {
              ChildWindow child = new ChildWindow ();
              child.Owner = this; // "this" is the parent
              child.ShowDialog();
          }
       }
      

      此外,如果您不想为所有孩子提供额外的任务栏...那么

      <Window x:Class="ChildWindow"           
              ShowInTaskbar="False" >
      </Window>
      

      【讨论】:

      • 如果this 不是一个窗口怎么办?我正在从 MFC 运行 WPF,所以我没有应用程序或主窗口。
      • 你想打开什么?只显示一个对话框?如果您不尝试将对话框附加到窗口,我不明白您的问题。
      • 正如我所说,“来自 MFC”...... MFC 类不是从 WPF 的 Window 派生的。我最近发现了 WindowInteropHelper.Owner ...尽管即使这样我们最终还是会出现隐藏的模式对话框。
      • 抱歉,错过了。我不确定如何让 WPF 的所有者成为 MFC。
      【解决方案4】:

      MVVM 模式的大部分原因是您的交互逻辑可以进行单元测试。出于这个原因,你不应该直接从 ViewModel 打开一个窗口,否则你会在单元测试的过程中弹出对话框。

      相反,您应该引发 View 将处理的事件并为您打开一个对话框。例如,请参阅这篇关于交互请求的文章:https://msdn.microsoft.com/en-us/library/gg405494(v=pandp.40).aspx#sec12

      【讨论】:

        【解决方案5】:

        添加“ShowInTaskbar”并将其设置为false。

        【讨论】:

          【解决方案6】:

          即使这篇文章有点老了,我希望我可以发布我的解决方案。 以上所有结果我都知道,并没有完全产生预期的结果。

          我正在为其他谷歌员工做这件事:)

          假设 f2 是您要在 f1 之上显示的窗口:

          f2.Owner = Window.GetWindow(this);
          f2.ShowDialog();
          

          就是这样,我保证它不会消失!

          HTH 伙计

          【讨论】:

            【解决方案7】:

            问题似乎Window.Owner有关,事实上,如果您根据以前对 Win32 API 和 WinForms 的了解来判断,缺少所有者将是导致此类问题的典型原因一个问题,但正如许多人指出的那样,在 WPF 的情况下不是这样。 Microsoft 不断改变事物以保持事物的趣味性。

            在 WPF 中,您可以与特定所有者建立一个对话框,并且您仍然可以让该对话框出现在任务栏中。因为为什么不。这是默认行为。因为为什么不。他们的理由是模态对话框不再是 kosher 了,所以你不应该使用它们;您应该使用无模式对话框,将其显示为单独的任务栏图标是有意义的,并且在任何情况下,用户都可以决定是否要将不同的应用程序窗口视为单独的图标,或者是否希望将它们分组。

            因此,他们试图执行此政策,完全无视任何可能想要违反他们的指导方针并创建模式对话框的人。因此,它们强制您明确声明您不希望在对话框中出现任务栏图标。

            要解决此问题,请在视图类的构造函数中执行以下操作:

            ShowInTaskbar = false;
            

            (这可能发生在InitializeComponent();之后

            这相当于 Xcalibur37 的答案,虽然我认为事情的方式,因为 WPF 强制你同时拥有一个 .cs 文件和一个 .xaml 文件,你不妨把不太可能改变的东西放在 @ 987654326@文件。

            【讨论】:

              猜你喜欢
              • 2021-05-05
              • 2015-05-29
              • 1970-01-01
              • 2012-10-23
              • 2014-10-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多