如何确定WPF窗口是否为模态窗口?

Mic*_*cah 29 .net wpf

找出窗口是否以模态方式打开的最简单方法是什么?

澄清:

我打开一个窗口打电话

myWindow.ShowDialog();
Run Code Online (Sandbox Code Playgroud)

我有一个带有"确定"和"取消"按钮的页脚,我只想在窗口以模态方式打开时显示.现在我意识到我可以通过这样做来设置属性:

myWindow.IsModal = true;
myWindow.ShowDialog();
Run Code Online (Sandbox Code Playgroud)

但我希望窗户本身能够做出决定.我想Loaded在窗口事件中检查它是否是模态的.

UPDATE

IsModal属性不会实际在WPF窗口存在.这是我创建的一个属性.ShowDialog()阻止当前线程.

我猜我可以ShowDialog()通过检查当前线程是否被阻止来确定是否打开了Window .我该怎么做呢?

CMe*_*rat 35

_showingAsDialog只要WPF窗口是模态对话框,就会有一个私有字段.您可以通过反射获得该值并将其合并到扩展方法中:

public static bool IsModal(this Window window)
{
    return (bool)typeof(Window).GetField("_showingAsDialog", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(window);
}
Run Code Online (Sandbox Code Playgroud)

当窗口显示为模态(ShowDialog)时,该值设置为true,窗口关闭后设置为false.

  • 不优雅,但一种检测方式。请注意,如果您升级 .Net 框架,Microsoft 可能会尝试更改私有字段的名称(例如此字段),因此您的代码可能会在以后崩溃。 (3认同)

Nas*_*ash 29

来自http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c95f1acb-5dee-4670-b779-b07b06afafff/

"System.Windows.Interop.ComponentDispatcher.IsThreadModal可以告诉你调用线程当前是否正在运行模态hwnd."

  • 如果模态对话框显示此无模式对话框,则此操作无效! (7认同)
  • 调用ShowModal后不立即工作.有些事件仍无法判断模态是否... (4认同)
  • 这是不可靠的 (2认同)

Ben*_*ter 5

好吧,自从我的最后一个想法被否决以来,我证明了这一点。这有效 - 我在一个新的 WPF 应用程序中对其进行了测试,所以我知道它有效:

在我的主窗口 (Window1) Loaded 事件中,我做了:

Dim frm As New Window2
frm.ShowDialog()
Run Code Online (Sandbox Code Playgroud)

在我的 Window2 中,我隐藏了 ShowDialog() 方法

Private _IsModal As Boolean = False 'This will be changed in the IsModal method

Public Property IsModal() As Boolean
  Get
    Return _IsModal
  End Get
  Set(ByVal value As Boolean)
    _IsModal = value
  End Set
End Property

Public Shadows Sub ShowDialog()
  IsModal = True
  MyBase.ShowDialog()
End Sub
Run Code Online (Sandbox Code Playgroud)

在我的 Loaded 事件中,然后我触发了一个消息框以确保 IsModal 属性从 False 更改为 True 并且它给我 True,所以我知道 IsModal 已设置。MyBase.ShowDialog() 然后强制将基类加载为 Modal。即使 ShowDialog() 方法未声明为可覆盖,Shadows 也允许我们覆盖默认行为。

虽然它不“自我确定”,但它不要求您从外部传入任何布尔值,也不要求您从外部设置 IsModal,而是将其设置在自身内部,如果您愿意,可以从外部访问它选择这样使用它。它仅在我们使用 ShowDialog() 方法加载时设置值,而不是在您使用 Show() 方法时设置。我怀疑你会找到一个更简单的方法来做到这一点。