What's the easiest way to figure out if a window is opened modally or not?
判断窗口是否以模式打开的最简单方法是什么?
CLARIFIACTION: I open a window calling
澄清:我打开一个窗口
myWindow.ShowDialog();
I have a footer with an "OK" & "Cancel" button that I only want to show if the window is opened modally. Now I realize I can set a property by doing this:
我有一个带有“OK”和“Cancel”按钮的页脚,我只想显示窗口是否以模式打开。现在我意识到我可以通过这样做来设置属性:
myWindow.IsModal = true;
myWindow.ShowDialog();
But I want the window it's self to make that determination. I want to check in the "Loaded" event of the window whether or not it is modal.
但我想要窗户是我自己做出的决定。我想检查窗口的“已加载”事件是否为模式。
UPDATE The "IsModal" property doesn't actually exist in a WPF window. It's a property that I have created. ShowDialog() blocks the current thread. I'm guessing I can determine if the Window is opened via ShowDialog() by checking if the current thread is blocked. How would I go about doing that?
更新“IsModal”属性实际上并不存在于WPF窗口中。这是我创建的一个属性。ShowDialog()阻塞当前线程。我猜我可以通过ShowDialog()检查当前线程是否被阻塞来确定窗口是否被打开。我该怎么做呢?
7 个解决方案
#1
28
From http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c95f1acb-5dee-4670-b779-b07b06afafff/
从http://social.msdn.microsoft.com/forums/en - us/wpf/thread/c95f1acb 5 -迪- 4670 b779 b07b06afafff/
"System.Windows.Interop.ComponentDispatcher.IsThreadModal can tell you if the calling thread is currently running a modal hwnd."
“System.Windows.Interop.ComponentDispatcher。IsThreadModal可以告诉你调用线程是否正在运行一个模态hwnd。
#2
28
There's a private field _showingAsDialog
whenever a WPF Window is a modal dialog. You could get that value via reflection and incorporate it in an extension method:
当WPF窗口是模态对话框时,会有一个私有字段_showingAsDialog。你可以通过反射获得这个值,并将其合并到扩展方法中:
public static bool IsModal(this Window window)
{
return (bool)typeof(Window).GetField("_showingAsDialog", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(window);
}
The value is set to true when the window is shown as modal (ShowDialog) and set to false once the window closes.
当窗口显示为modal (ShowDialog)时,该值设置为true,当窗口关闭时设置为false。
#3
3
Okay, since my last idea got voted down, I proved it. this works - and I tested it in a new WPF application, so I know it works:
好吧,既然我的上一个想法被否决了,我就证明了。这是可行的——我在一个新的WPF应用程序中测试了它,所以我知道它是可行的:
In my main Window's (Window1) Loaded event, I did:
在主窗口(Window1)加载事件中,我这样做了:
Dim frm As New Window2
frm.ShowDialog()
In my Window2 I shadowed the ShowDialog() method
在我的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
In my Loaded event, I then fired off a message box to make sure that the IsModal property got changed from False to True and it gives me True, so I know IsModal was set. MyBase.ShowDialog() then forces the base class to be loaded as Modal. Shadows allows us to override the default behaviour even though the ShowDialog() method wasn't declared as overridable.
在我加载的事件中,我触发了一个消息框,以确保IsModal属性被从False改为True,并且它给我True,所以我知道IsModal设置了。MyBase.ShowDialog()然后强制将基类加载为Modal。阴影允许我们重写默认行为,即使ShowDialog()方法没有声明为可重写。
While it doesn't "self determine" it doesn't require you to pass in any boolean value from outside, and doesn't require you to set the IsModal from outside, it sets it inside itself, it's accessible from outside if you so chose to use it that way. It sets the value only if it us loaded using the ShowDialog() method and not if you use the Show() method. I doubt you'll find a much simpler method of doing this.
虽然它不“自定义”,但它不需要你从外部传递任何布尔值,也不需要你从外部设置IsModal,它在自己内部设置,如果你选择这样使用它,它可以从外部访问。它只在使用ShowDialog()方法加载时设置值,而在使用Show()方法时设置值。我怀疑你会找到一种更简单的方法来做这件事。
#4
2
Here is a converter fragment which is useful for hiding elements when the window is invoked by the ShowDialog method:
下面是一个转换器片段,当ShowDialog方法调用窗口时,它可以用来隐藏元素:
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Window window = value as Window;
if (window != null)
{
var showingAsDialogFieldInfo = typeof(System.Windows.Window).GetField("_showingAsDialog",
BindingFlags.NonPublic | BindingFlags.Instance);
if ((bool) showingAsDialogFieldInfo.GetValue(window) == false)
{
return Visibility.Visible;
}
}
return Visibility.Hidden;
}
#5
0
Using UI Automation in Windows, I have come up with something like this:
在Windows中使用UI自动化,我想到了这样的事情:
void Window2_Loaded(object sender, RoutedEventArgs e)
{
var hwnd = new System.Windows.Interop.WindowInteropHelper(this).Handle;
var el = AutomationElement.FromHandle(hwnd);
Object oPattern = null;
if (el.TryGetCurrentPattern(WindowPattern.Pattern, out oPattern))
{
var pattern = oPattern as WindowPattern;
this.Title = pattern.Current.IsModal.ToString();
}
}
But this seems not working. There is an IsModal property http://msdn.microsoft.com/en-us/library/system.windows.automation.provider.iwindowprovider.ismodal.aspx there must be a proper way to get AutomationElement for the window and check whether IsModal property of it is true via Automation.
但这似乎行不通。有一个IsModal属性http://msdn.microsoft.com/en- us/library/system.windows.autom.automation.iwindowprovider.iwindowprovider.ismodal.aspx必须有一个合适的方法来获取窗口的AutomationElement,并通过自动化检查它的IsModal属性是否为真。
#6
0
a modal window will stop processing until it is closed.
模态窗口将停止处理,直到关闭为止。
This example shows displaying a non-modal window
这个例子显示了一个非模态窗口
dim f as myWindow
f.show
someOtherMethod()
In this example, someOtherMethod runs immediately after the window is launched.
在本例中,另一个方法在窗口启动后立即运行。
This example shows displaying a modal one:
这个例子显示了一个模态的:
dim f as myWindow
f.showDialog
someOtherMethod()
In this example, someOtherMethod() won't run until the ShowDialog method returns (which means that the modal window has been closed)
在本例中,someOtherMethod()在ShowDialog方法返回之前不会运行(这意味着模式窗口已经关闭)
EDIT due to clarification: Override the ShowDialog and pass in a boolean.
由于澄清而编辑:覆盖ShowDialog并传入一个布尔值。
dim f as MyWindow
f.ShowDialog(true)
then in the window
然后在窗口
Public Function Shadows ShowDialog(myVar as boolean) As Boolean
if myVar then ShowButtons()
return mybase.ShowDialog()
End Function
#7
-2
Would it be possible to check the window's parent to see if it is disabled? I'm not sure if this can be done via WPF APIs or not, but if nothing else you could get the HWND of the WPF window, get its parent via Win32 P/Invoke (or whatever), and then check to see if it is disabled or not.
是否可以检查窗口的父窗口,看看它是否被禁用?我不确定这是否可以通过WPF api来实现,但是如果您无法获得WPF窗口的HWND,请通过Win32 P/Invoke(或其他方式)获取它的父窗口,然后检查它是否被禁用。
Definitely not a clean method, but it seems like it could work.
这绝对不是一个干净的方法,但它似乎可以工作。
#1
28
From http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c95f1acb-5dee-4670-b779-b07b06afafff/
从http://social.msdn.microsoft.com/forums/en - us/wpf/thread/c95f1acb 5 -迪- 4670 b779 b07b06afafff/
"System.Windows.Interop.ComponentDispatcher.IsThreadModal can tell you if the calling thread is currently running a modal hwnd."
“System.Windows.Interop.ComponentDispatcher。IsThreadModal可以告诉你调用线程是否正在运行一个模态hwnd。
#2
28
There's a private field _showingAsDialog
whenever a WPF Window is a modal dialog. You could get that value via reflection and incorporate it in an extension method:
当WPF窗口是模态对话框时,会有一个私有字段_showingAsDialog。你可以通过反射获得这个值,并将其合并到扩展方法中:
public static bool IsModal(this Window window)
{
return (bool)typeof(Window).GetField("_showingAsDialog", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(window);
}
The value is set to true when the window is shown as modal (ShowDialog) and set to false once the window closes.
当窗口显示为modal (ShowDialog)时,该值设置为true,当窗口关闭时设置为false。
#3
3
Okay, since my last idea got voted down, I proved it. this works - and I tested it in a new WPF application, so I know it works:
好吧,既然我的上一个想法被否决了,我就证明了。这是可行的——我在一个新的WPF应用程序中测试了它,所以我知道它是可行的:
In my main Window's (Window1) Loaded event, I did:
在主窗口(Window1)加载事件中,我这样做了:
Dim frm As New Window2
frm.ShowDialog()
In my Window2 I shadowed the ShowDialog() method
在我的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
In my Loaded event, I then fired off a message box to make sure that the IsModal property got changed from False to True and it gives me True, so I know IsModal was set. MyBase.ShowDialog() then forces the base class to be loaded as Modal. Shadows allows us to override the default behaviour even though the ShowDialog() method wasn't declared as overridable.
在我加载的事件中,我触发了一个消息框,以确保IsModal属性被从False改为True,并且它给我True,所以我知道IsModal设置了。MyBase.ShowDialog()然后强制将基类加载为Modal。阴影允许我们重写默认行为,即使ShowDialog()方法没有声明为可重写。
While it doesn't "self determine" it doesn't require you to pass in any boolean value from outside, and doesn't require you to set the IsModal from outside, it sets it inside itself, it's accessible from outside if you so chose to use it that way. It sets the value only if it us loaded using the ShowDialog() method and not if you use the Show() method. I doubt you'll find a much simpler method of doing this.
虽然它不“自定义”,但它不需要你从外部传递任何布尔值,也不需要你从外部设置IsModal,它在自己内部设置,如果你选择这样使用它,它可以从外部访问。它只在使用ShowDialog()方法加载时设置值,而在使用Show()方法时设置值。我怀疑你会找到一种更简单的方法来做这件事。
#4
2
Here is a converter fragment which is useful for hiding elements when the window is invoked by the ShowDialog method:
下面是一个转换器片段,当ShowDialog方法调用窗口时,它可以用来隐藏元素:
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Window window = value as Window;
if (window != null)
{
var showingAsDialogFieldInfo = typeof(System.Windows.Window).GetField("_showingAsDialog",
BindingFlags.NonPublic | BindingFlags.Instance);
if ((bool) showingAsDialogFieldInfo.GetValue(window) == false)
{
return Visibility.Visible;
}
}
return Visibility.Hidden;
}
#5
0
Using UI Automation in Windows, I have come up with something like this:
在Windows中使用UI自动化,我想到了这样的事情:
void Window2_Loaded(object sender, RoutedEventArgs e)
{
var hwnd = new System.Windows.Interop.WindowInteropHelper(this).Handle;
var el = AutomationElement.FromHandle(hwnd);
Object oPattern = null;
if (el.TryGetCurrentPattern(WindowPattern.Pattern, out oPattern))
{
var pattern = oPattern as WindowPattern;
this.Title = pattern.Current.IsModal.ToString();
}
}
But this seems not working. There is an IsModal property http://msdn.microsoft.com/en-us/library/system.windows.automation.provider.iwindowprovider.ismodal.aspx there must be a proper way to get AutomationElement for the window and check whether IsModal property of it is true via Automation.
但这似乎行不通。有一个IsModal属性http://msdn.microsoft.com/en- us/library/system.windows.autom.automation.iwindowprovider.iwindowprovider.ismodal.aspx必须有一个合适的方法来获取窗口的AutomationElement,并通过自动化检查它的IsModal属性是否为真。
#6
0
a modal window will stop processing until it is closed.
模态窗口将停止处理,直到关闭为止。
This example shows displaying a non-modal window
这个例子显示了一个非模态窗口
dim f as myWindow
f.show
someOtherMethod()
In this example, someOtherMethod runs immediately after the window is launched.
在本例中,另一个方法在窗口启动后立即运行。
This example shows displaying a modal one:
这个例子显示了一个模态的:
dim f as myWindow
f.showDialog
someOtherMethod()
In this example, someOtherMethod() won't run until the ShowDialog method returns (which means that the modal window has been closed)
在本例中,someOtherMethod()在ShowDialog方法返回之前不会运行(这意味着模式窗口已经关闭)
EDIT due to clarification: Override the ShowDialog and pass in a boolean.
由于澄清而编辑:覆盖ShowDialog并传入一个布尔值。
dim f as MyWindow
f.ShowDialog(true)
then in the window
然后在窗口
Public Function Shadows ShowDialog(myVar as boolean) As Boolean
if myVar then ShowButtons()
return mybase.ShowDialog()
End Function
#7
-2
Would it be possible to check the window's parent to see if it is disabled? I'm not sure if this can be done via WPF APIs or not, but if nothing else you could get the HWND of the WPF window, get its parent via Win32 P/Invoke (or whatever), and then check to see if it is disabled or not.
是否可以检查窗口的父窗口,看看它是否被禁用?我不确定这是否可以通过WPF api来实现,但是如果您无法获得WPF窗口的HWND,请通过Win32 P/Invoke(或其他方式)获取它的父窗口,然后检查它是否被禁用。
Definitely not a clean method, but it seems like it could work.
这绝对不是一个干净的方法,但它似乎可以工作。