Application.OpenForms.Count = 0 总是 [英] Application.OpenForms.Count = 0 always

查看:16
本文介绍了Application.OpenForms.Count = 0 总是的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这种情况.Application.OpenForms 没有返回正确的结果.即 Application.OpenForms.Count = 0 总是..

I have this situation. Application.OpenForms doesnt return the right result. ie Application.OpenForms.Count = 0 always..

获取表单的目的是获取表单的所有者,以便我可以将所有者作为MessageBox.Show() 函数的参数传递.

Purpose of getting the form is get the owner of the Form so that I can pass the owner as the parameter of the MessageBox.Show() function.

推荐答案

Windows 窗体中存在一个错误,导致窗体从 Application.OpenForms 集合中消失.当您在创建窗口之后分配 ShowInTaskbar、FormBorderStyle、ControlBox、Min/MaximizedBox、RightToLeftLayout、HelpButton、Opacity、TransparencyKey、ShowIcon 或 MdiParent 属性时,会发生这种情况..这些属性的特殊之处在于它们在本机 CreateWindowEx() 调用中被指定为样式标志.此示例表单演示了该错误:

There's a bug in Windows Forms that makes a form disappear from the Application.OpenForms collection. This will happen when you assign the ShowInTaskbar, FormBorderStyle, ControlBox, Min/MaximizedBox, RightToLeftLayout, HelpButton, Opacity, TransparencyKey, ShowIcon or MdiParent property after the window was created. These properties are special in that they are specified as style flags in the native CreateWindowEx() call. This sample form demonstrates the bug:

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
        button1.Click += button1_Click;
    }
    private void button1_Click(object sender, EventArgs e) {
        Console.WriteLine(Application.OpenForms.Count);
        this.ShowInTaskbar = !this.ShowInTaskbar;
        Console.WriteLine(Application.OpenForms.Count);
    }
}

Windows 窗体必须再次调用 CreateWindowEx() 以使更改的属性生效,传递不同的样式标志.首先销毁原始窗口会产生除非常明显的闪烁之外的副作用,其中之一是 Application 类因为看到窗口消失而失去了对窗体的跟踪.由于创建新窗口时不会将其添加回来的错误.通过仅在构造函数中设置属性来避免该错误,即在调用 CreateWindowEx() 之前运行的代码,而不是在任何事件处理程序中.

Windows Forms must call CreateWindowEx() again to make the changed property effective, passing different style flags. Destroying the original window first has side effects beyond the very noticeable flicker, one of them is that the Application class loses track of the form since it sees the window disappear. With the bug that it doesn't add it back when the new window is created. Avoid the bug by setting the property only in the constructor, code that runs before CreateWindowEx() is called, not in any event handlers.

通常,由于此错误,请避免依赖 OpenForms.通过其构造函数为需要显示消息框的类提供对表单实例的引用.MessageBox 通常自己正确地找出父窗口,顺便说一句,它会选择活动窗口,并且在 99% 的情况下都是正确的.如果您需要它从工作线程调用 BeginInvoke(),请确保在构造函数中复制 SynchronizationContext.Current 并稍后调用其 Post() 方法.确保您的库也适用于其他 GUI 类库.

In general, avoid relying on OpenForms due to this bug. Give the class that needs to display the message box a reference to the form instance through its constructor. MessageBox usually figures out a parent window by itself correctly btw, it will pick the active window and that's correct 99% of the time. If you need it to call BeginInvoke() from a worker thread then be sure to copy SynchronizationContext.Current in your constructor and call its Post() method later. Ensures your library will also work with other GUI class libraries.

这篇关于Application.OpenForms.Count = 0 总是的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆