2012-07-04 10 views
1

因为这是一个相当大的项目,我经常需要从类中访问其他形式的对象,所以我首先在我的program.cs类中创建一个静态变量, MainForm“,它是一个Windows窗体。我从DataManger.cs类实例化对象'Program.MainFormObj = new MainForm()',然后调用Show方法以显示我的Form。它看起来像表单的Paint事件没有完成,但它确实随着一些控件的绘制而启动。大概是因为主线程(这全部在主线程中运行)被下一个语句“占用”。我想,不管已知的问题,我会使用Application.DoEvents()来暂时解决这个问题。按照我的想象,它起作用了,但仅在一定程度上。如果我放置一个像MessageBox.Show()这样的阻塞方法,我可以在后台查看完全无瑕疵的表单,但只要按下'OK'并且代码继续执行,整个应用程序就会退出。当我显示新表格时,控件是白色的

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

+1

你至少违反了两条“永远不要这样做!” Winforms编程规则。你还可以做什么只能猜到。这是目前的形式不是一个可回答的问题,请访问您当地的书店或图书馆,找到正确的Winforms编程技术书籍。 –

回答

2

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

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

对抗WinForms的作品在中期会比现在投入更多的时间去做正确的事情。

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

UPDATE

基于您的代码示例中,我看到你大概就比主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线程调用用户界面代码:

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

+0

感谢您的回复。不幸的是,对于这个项目,由于时间限制,我没有其他选择,只能使用WinForms。我可以定义今年夏天研究MVC模式和WPF,我认为从长远来看它更有利。您是否知道解决此问题的任何方法,以便我可以实现该解决方案的当前结构? –

+0

没有足够的信息来确定问题所在。你能创建一个小的测试用例来证明问题并发布代码,或者至少是相关的部分吗? –

+0

更新了我的答案(认为问题已解决)。 –

相关问题