Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 如何确定WPF窗口是否为模态窗口?_.net_Wpf - Fatal编程技术网

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

.net 如何确定WPF窗口是否为模态窗口?,.net,wpf,.net,Wpf,判断窗口是否以模式打开的最简单方法是什么 澄清: 我打开窗户打电话 myWindow.ShowDialog(); 我有一个带有“OK”和“Cancel”按钮的页脚,我只想在窗口以模式打开时显示它。现在我意识到我可以通过以下操作设置属性: myWindow.IsModal = true; myWindow.ShowDialog(); 但我想让窗户自己做出决定。我想检查窗口的Loaded事件是否为模态 更新 WPF窗口中实际上不存在IsModal属性。这是我创造的财产显示对话框()阻止当前线程

判断窗口是否以模式打开的最简单方法是什么

澄清:

我打开窗户打电话

myWindow.ShowDialog();
我有一个带有“OK”和“Cancel”按钮的页脚,我只想在窗口以模式打开时显示它。现在我意识到我可以通过以下操作设置属性:

myWindow.IsModal = true;
myWindow.ShowDialog();
但我想让窗户自己做出决定。我想检查窗口的
Loaded
事件是否为模态

更新

WPF窗口中实际上不存在
IsModal
属性。这是我创造的财产<代码>显示对话框()阻止当前线程


我猜我可以通过检查当前线程是否被阻塞来确定窗口是否通过
ShowDialog()
打开。我该怎么做呢?

模式窗口将停止处理,直到关闭

此示例显示如何显示非模式窗口

dim f as myWindow
f.show
someOtherMethod()
在本例中,someOtherMethod在启动窗口后立即运行

此示例显示了如何显示模式一:

dim f as myWindow
f.showDialog
someOtherMethod()
在本例中,直到ShowDialog方法返回(这意味着模式窗口已关闭),someOtherMethod()才会运行

因澄清而编辑: 覆盖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 

好吧,自从我的上一个想法被否决后,我证明了这一点。这是可行的——我在一个新的WPF应用程序中测试了它,所以我知道它是可行的:

在我的主窗口(Window1)加载事件中,我执行了以下操作:

Dim frm As New Window2
frm.ShowDialog()
在Window2中,我对ShowDialog()方法进行了阴影处理

在我加载的事件中,我随后启动了一个消息框,以确保IsModal属性从False更改为True,并提供True,因此我知道IsModal已设置。然后,ShowDialog()强制将基类作为模态加载。Shadows允许我们重写默认行为,即使ShowDialog()方法未声明为可重写


虽然它不“自行决定”,也不需要您从外部传入任何布尔值,也不需要您从外部设置IsModal,但它将IsModal设置为内部,如果您选择这样使用它,则可以从外部访问它。它仅在使用ShowDialog()方法加载时设置值,而在使用Show()方法时不设置值。我怀疑您是否会找到一种更简单的方法来实现这一点。

使用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属性必须有一个正确的方法来获取窗口的AutomationElement,并通过Automation检查它的IsModal属性是否为true。

是否可以检查窗口的父级以查看它是否被禁用?我不确定这是否可以通过WPF API完成,但如果没有其他方法,您可以获取WPF窗口的HWND,通过Win32 P/Invoke(或其他什么)获取其父窗口,然后检查它是否被禁用

绝对不是一个干净的方法,但它似乎可以工作。


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

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

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

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

以下是一个转换器片段,当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;
    }

您还可以创建一个从窗口继承的新类对话框。在Dialog类中创建一个私有变量IsDialog,并使用new重写ShowDialog函数。调用ShowDialog时,将IsDialog变量设置为true:

public class Dialog : Window
{
    private bool IsDialog;

    new public bool? ShowDialog()
    {
        IsDialog = true;
        return base.ShowDialog();
    }
}

如果未使用ShowDialog()打开窗口,则Window不允许您设置Window.DialogResult的值。因此,您可以尝试设置Window.DialogResult并查看它是否引发异常。

+1我认为这比需要使用IsModal()属性更可取。这正是我想要的。令人惊叹的!调用ShowModal后不会立即工作。某些事件仍然无法判断是否为模态…如果模态对话框显示此非模态对话框,则此操作不起作用!这是不可靠的,因为主应用程序窗口创建了一个模式对话框,并且这种方法在加载的
中错误地报告了“false”。也许有什么改变了?@CMerat给出的答案是正确的。(Win10,WPF4.5)不是优雅,而是一种检测方式。请注意,如果您升级.Net framework,Microsoft可能会尝试更改此类私有字段的名称,因此您的代码稍后可能会中断。
public class Dialog : Window
{
    private bool IsDialog;

    new public bool? ShowDialog()
    {
        IsDialog = true;
        return base.ShowDialog();
    }
}