c# - Application.OpenForms.Count = 0 总是

标签 c# .net winforms

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

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

最佳答案

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

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() 之前运行的代码)而不是任何事件处理程序中设置属性来避免错误。

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

关于c# - Application.OpenForms.Count = 0 总是,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3751554/

相关文章:

c# - log4net:使用 ILog 与 ILogger 之间的区别/优势是什么?

c# - SSRS 最后执行数据集

c# - 何时选择从代码隐藏而不是外部 js 文件进行 Javascript 注入(inject)

c# - 如何设置刻度线的间隔?

c# - 如何防止 Visual Studio 在继承的控件中设置我的默认字体大小

c# - 引用并存储动态创建的控件中的数据?

C# 套接字 : is multiple sending less efficient than a single send?

c# - 在 Umbraco 中调用 node.NiceUrl 给我 #

.net - 如何以编程方式查找正确的 Microsoft Office 产品版本号(和服务包)?

c# - 如何解决使用 C# 在 Windows 服务上捕获屏幕截图的问题?