找出窗口是否以模态方式打开的最简单方法是什么?
澄清:
我打开一个叫
的窗口myWindow.ShowDialog();
我有一个“OK”的页脚&如果窗口以模态方式打开,我只想显示“取消”按钮。现在我意识到我可以通过这样做来设置属性:
myWindow.IsModal = true;
myWindow.ShowDialog();
但我希望窗户本身能够做出决定。我想检查窗口的Loaded
事件是否是模态的。
更新
IsModal
属性实际上不存在于WPF窗口中。这是我创建的一个属性。 ShowDialog()
阻止当前线程。
我猜我可以通过检查当前线程是否被阻止来确定是否通过ShowDialog()
打开了Window。我该怎么做呢?
答案 0 :(得分:30)
来自http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c95f1acb-5dee-4670-b779-b07b06afafff/
“System.Windows.Interop.ComponentDispatcher.IsThreadModal可以告诉您调用线程当前是否正在运行模态hwnd。”
答案 1 :(得分:29)
每当WPF窗口是模态对话框时,都会有一个私有字段_showingAsDialog
。您可以通过反射获得该值并将其合并到扩展方法中:
public static bool IsModal(this Window window)
{
return (bool)typeof(Window).GetField("_showingAsDialog", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(window);
}
当窗口显示为模态(ShowDialog)时,该值设置为true,窗口关闭后设置为false。
答案 2 :(得分:4)
好吧,既然我的最后一个想法被否决了,我证明了这一点。这工作 - 我在一个新的WPF应用程序中测试它,所以我知道它的工作原理:
在我的主窗口(Window1)Loaded事件中,我做了:
Dim frm As New Window2
frm.ShowDialog()
在我的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
在我的Loaded事件中,我然后触发了一个消息框以确保IsModal属性从False更改为True并且它给了我True,所以我知道IsModal已设置。 MyBase.ShowDialog()然后强制基类作为Modal加载。阴影允许我们覆盖默认行为,即使ShowDialog()方法未被声明为可覆盖。
虽然它不是“自我确定”,但它不要求你从外部传递任何布尔值,并且不需要你从外部设置IsModal,它将其设置在自身内部,它可以从外部访问如果你这样选择使用它。它仅在我们使用ShowDialog()方法加载时设置值,而不是在使用Show()方法时加载。我怀疑你会找到一种更简单的方法。
答案 3 :(得分:2)
这是一个转换器片段,用于在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;
}
答案 4 :(得分:0)
模态窗口将停止处理直到它关闭。
此示例显示显示非模态窗口
dim f as myWindow
f.show
someOtherMethod()
在此示例中,someOtherMethod在窗口启动后立即运行。
此示例显示显示模式1:
dim f as myWindow
f.showDialog
someOtherMethod()
在这个例子中,someOtherMethod()在ShowDialog方法返回之前不会运行(这意味着模态窗口已经关闭)
由于澄清而编辑: 覆盖ShowDialog并传入一个布尔值。
dim f as MyWindow
f.ShowDialog(true)
然后在窗口
Public Function Shadows ShowDialog(myVar as boolean) As Boolean
if myVar then ShowButtons()
return mybase.ShowDialog()
End Function
答案 5 :(得分:0)
在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();
}
}
但这似乎不起作用。有一个IsModal属性http://msdn.microsoft.com/en-us/library/system.windows.automation.provider.iwindowprovider.ismodal.aspx必须有一个正确的方法来获取窗口的AutomationElement,并通过自动化检查它的IsModal属性是否为真。
答案 6 :(得分:0)
您还可以创建一个继承自 Window 的新类 Dialog 。在Dialog类中创建一个私有变量 IsDialog ,并使用new覆盖 ShowDialog 函数。调用ShowDialog时,将IsDialog变量设置为true:
public class Dialog : Window
{
private bool IsDialog;
new public bool? ShowDialog()
{
IsDialog = true;
return base.ShowDialog();
}
}
答案 7 :(得分:-1)
是否可以检查窗口的父级以查看它是否已禁用?我不确定这是否可以通过WPF API完成,但如果没有别的你可以获得WPF窗口的HWND,通过Win32 P / Invoke(或其他)获取其父,然后检查它是否是否被禁用。
绝对不是一个干净的方法,但似乎它可以工作。
答案 8 :(得分:-1)
Window不允许您为Window.DialogResult设置值。因此,您可以尝试设置Window.DialogResult并查看它是否引发异常。