当我显示新表格时,控件是白色的

时间:2012-07-04 00:09:13

标签: c# .net forms controls paint

因为这是一个非常大的项目,我经常需要从类中访问其他形式的对象,我首先在我的program.cs类中创建一个静态变量,类型为'MainForm',这是一个Windows窗体。

从我的DataManger.cs类中,我实例化对象'Program.MainFormObj = new MainForm()',然后调用Show方法以显示我的Form。看起来表单的Paint事件没有完成,但它会在绘制一些控件时启动。大概是因为主线程(这是所有在主线程上运行的线程)被下一个语句“占用”。我想,无论已知问题,我都会使用Application.DoEvents()来暂时解决这个问题。正如我想象的那样,它起作用,但只是在一定程度上。如果我使用像MessageBox.Show()这样的阻塞方法,我可以在后台查看完全完美的表单,但只要按“确定”,代码就会继续运行整个应用程序。

我真的被困住了。尽管在这里广泛搜索并使用谷歌我找不到一个apporpiate答案。我这样做了这个帖子:Form.Show() is not showing it's child controls但是给定的解决方案不适合我的解决方案。非常感谢任何帮助,谢谢。

1 个答案:

答案 0 :(得分:2)

如果这是一个大项目,现在就投入时间来重构它。

  • 考虑一个MVC模式。您可以do what with WinForms,而不仅仅是更新的UI技术。
  • 如果您不选择WinForms,至少需要单独的用户界面和数据(Data Binding是您的朋友)。
  • 在不同表单共享通用功能时构建可重用组件。

在中期战胜WinForms的工作方式将比现在投入时间做得更加昂贵。

如果您对该技术有任何选择,请考虑使用WPF。 WPF有一个学习曲线,但现在可能值得投资学习。

<强>更新

根据您的代码示例,我发现您可能在主UI线程以外的线程上创建了一些表单。虽然这是允许的,但它会创建非常混乱的代码,因为表单只能从创建的线程更新

使这项工作最简单的方法可能是更新HandleIncomingData以调用主UI线程上的Show()调用。

应该有一种方法可以通过静态方法干净地做到这一点,如下所述:

https://stackoverflow.com/a/505361/141172

但是,当我尝试这样做时,我发现SynchronizationContext始终为空。我确定我只是错过了一步。

我能够通过滥用LoginForm来解决问题(假设,也许是错误的,表单始终可用。如果没有,也许只为线程封送创建一个特殊的表单。)

黑客看起来像这样:

Program.MainForm = new MainForm();
try
{

    MessageBox.Show("Login Success.", "Login", MessageBoxButtons.OK, MessageBoxIcon.Information);

            // Abusing LoginForm's Invoke method.  Code assumes LoginForm is always available.
    Program.LoginForm.Invoke((MethodInvoker)delegate
    {
        Program.MainForm.Show();
    });


}
catch (Exception Ex)
{
    MessageBox.Show(Ex.ToString()); //Debuging purposes
}

顺便说一句,有一个很好的扩展方法,可以轻松地从非UI线程调用UI代码:

https://stackoverflow.com/a/3588137/141172