【问题标题】:When would ShowDialog() return null?ShowDialog() 什么时候返回 null?
【发布时间】:2009-06-13 06:16:39
【问题描述】:

WPF 的Window.ShowDialog 方法返回一个可为空的布尔值。 CommonDialog.ShowDialog也是如此。

现在,我了解这些将返回 false(用户单击取消或按 Esc)以及何时返回 true(代码将 Window.DialogResult 设置为 true,可能是为了响应单击 OK)的情况。但是为空?

我的第一个想法是单击标题栏的关闭按钮可能会返回 null。但是文档声明(我通过测试确认)the title-bar Close button is treated as a Cancel

那么Window.ShowDialogCommonDialog.ShowDialog 什么时候会返回null?

【问题讨论】:

  • 你必须热爱 MS 文档。 “布尔类型的 Nullable)>) 值,表示用户如何关闭窗口。”哎呀,这有帮助。
  • 听起来像是不允许作者与开发人员交谈和提问的文档,但只能访问他们在屏幕上的内容...

标签: wpf null showdialog


【解决方案1】:

该方法总是返回 true 或 false,这总是等于窗口关闭时的 DialogResult 属性。

但在窗口关闭之前DialogResult属性为空,另一个线程可以检查该属性。所以返回值是一个可以为空的布尔值来匹配属性是有道理的,即使它实际上从来不是空的。

【讨论】:

  • 不知道你从哪里得到另一个线程可以检查 DialogResult 的想法。如果你尝试,你会得到一个 InvalidOperationException(“调用线程无法访问这个对象,因为另一个线程拥有它。”)
  • 不是另一个线程,但是在对话框的事件处理程序上运行(比如说)的任何代码都可以在 DialogResult 完成之前检索它的值。我个人认为这是一个糟糕的设计选择。它应该是不可为空的,如果在对话框退出之前访问,getter 会抛出异常。
  • 我刚刚让这个方法返回null 并去这个问题查找它,所以(至少从现在开始)这个方法肯定可以返回 null。没有任何例外,无论出于何种原因,窗口根本没有出现,这个方法只是返回了 - null。我现在除了调试 WPF 代码以找出原因之外别无他法。
  • 将 DialogResult 设置为 false 或 true 将关闭窗口。将属性设置为其当前值通常不会有副作用(来自 Window 源代码的注释:“//根据新设计,将 DialogResult 设置为其当前值不会有任何影响。”),因此更简洁让 DialogResult 具有与其中任何一个不同的初始值 - 因此它必须可以为空。当然,ShowDialog() 方法不必直接返回 DialogResult 的值,但这就是它所做的 - 或者更确切地说,它的支持字段 _dialogResult。
【解决方案2】:

如果我在按钮的 Click 事件中返回 DialogResult = null,则窗口保持打开状态。

private void OkButton_Click(object sender, RoutedEventArgs e)
{
   Button btn = sender as Button;
   if ( btn != null )
   {
       // forces all control to update...
       btn.Focus();
   }

   // TEST IF OK TO CLOSE
   bool rc = _vm.ProcessOkCommand();
   if (rc)
   {
      DialogResult = true;
   }
   else
   {
      DialogResult = null;
   }
}


<Button Content="OK" Name ="cmdOK" IsDefault="True" Click="OkButton_Click"/>

【讨论】:

  • 对,这就是我的意思——看起来 ShowDialog 永远不会返回 null。
  • 设置DialogResult = null;比什么都不做好。我猜实际上两者都是一样的。如果我错了,请纠正我。
【解决方案3】:

我可以举一个我刚刚遇到的例子。当您执行以下步骤时,Window.ShowDialog() 将返回 null:

  • 首先关闭Application 的所有窗口。
  • 到目前为止,使用 new 关键字实例化的所有其他 Window 对象均已关闭。
  • 您尝试实例化一个新的Window 并尝试在其上调用Window.ShowDialog()。它将返回 null。

这大概是因为您没有现有的Window,新对话框可以绑定到该Window 下,以便其行为类似于拥有最顶层窗口状态的对话框。

【讨论】:

    【解决方案4】:

    在非常特殊的情况下调用window.ShowDialog() 会返回null,这是我偶然遇到的:

    如果window.Closing事件被以下方式捕获

            var window = new DialogTestWindow();
            window.Closing += (o, e) => { e.Cancel = true; window.Hide(); };
            MessageBox.Show(window.ShowDialog().ToString());
    

    然后从对话窗口设置DialogResult = trueDialogResult = false 将导致window.ShowDialog() 调用返回null。从对话窗口调用Hide()会导致它返回false。

    编辑:Window 源代码中的 cmets 明确表示,其意图是对 ShowDialog() 的调用永远不应返回 null。但是,当从 Closing 事件中调用 Hide() 时,应防止这种情况发生的各种检查失败:Hide()_dialogResult 设置为 false,但随后会检查是否已取消窗口关闭它为空。

    【讨论】:

      猜你喜欢
      • 2021-10-11
      • 1970-01-01
      • 2011-04-18
      • 1970-01-01
      • 2012-06-03
      • 2015-02-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多