ShowDialog(Compact Framework)后表单不刷新

时间:2010-09-21 17:49:21

标签: compact-framework refresh paint showdialog

我在Compact Framework中遇到了一个奇怪的表单绘制问题。我有一个登录对话框,基本上是一个小表单,使用ShowDialog打开另一个。刷卡时,应该关闭登录对话框,然后执行一些登录任务,然后激活后面的表格。问题是登录对话框后面的表单没有刷新,因此在某些用户操作刷新后面的表单后才会删除登录对话框。这可能是由于登录任务部分中的繁重处理,但我找不到解决此问题的方法。

基本上,在执行繁重的登录任务之前,我想要一种强制应用程序关闭对话框并再次绘制所有内容的方法。我尝试了很多刷新方法而没有任何运气:

Form loginDialog = new Form();
DialogResult result = loginDialog.ShowDialog();
loginDialog.Dispose();

//I've tried everything at this point to get the form to refresh before performing
//login tasks
this.Refresh();
this.Invalidate();
Application.DoEvents();


PerformHeavyLoginTasks();

有谁知道会出现什么问题?感谢

2 个答案:

答案 0 :(得分:1)

好的,我想出来了。问题在于背景窗体上的自定义控件,它使用矩形等手动绘制自己。我认为这是一个紧凑的框架错误,因为我在该控件上调用了Refresh和Invalidate,它应该重新绘制。我必须创建一个方法来直接调用控件的OnPaint覆盖,因为Invalidate和Refreshed几乎被忽略了。

答案 1 :(得分:0)

我认为,这个问题是你在这里没有完全理解系统方面的情况。

当你的前窗(对话框)被解除时,背景窗口(表格)被赋予focu和tol以重新绘制对话框所在的剪辑区域。这通过PostMessage调用发生,该调用发送一个Windows消息,该消息必须在Application.Run调用的内容中弹出,翻译和调度。

按照设计,这是一个相当慢的过程,因为用户界面不应该抢占重要的事情。

如果你在PostMessage发生后立即进行大量处理,那么这些窗口消息的处理通常会变慢,最终导致UI显示为“已锁定”或绘制速度非常慢。如果您正在进行的处理与UI处于同一个线程,则会加剧这种情况。

为什么你的努力没有让事情变得更好?

  • 调用刷新只会发送另一条消息。该消息现在可以进行处理,因此实际上会使事情变得更糟。
  • 调用Invalidate与Refresh非常相同,只是异步。再次,它使事情变得更糟。
  • DoEvents告诉消息泵弹出,翻译和发送消息。该调度仍然必须在UI线程上处理,因此在线程有时间完成工作之前(即在处理之后)才会发生注意事项。

那么我们如何“修复”这个呢?

第一步通常是将处理放在一个单独的线程上,以允许调度程序在UI和处理线程之间循环执行任务,直到默认量程。 Thgis意味着在允许某种绘图发生之前,处理只能使UI饿死最多100ms(假设线程优先级相等)。

new Thread(PerformHeavyLoginTasks)
{
    IsBackground = true
}.Start();

您可以更进一步,让UI在处理过程中“快速启动”(本例中为10ms):

new Thread(new ThreadStart(delegate
    {
        Thread.Sleep(10);
        PerformHeavyLoginTasks();
    }))
{
    IsBackground = true
}.Start();

当然,这可能意味着如果要显示的UI依赖于处理结果,您现在需要异步处理下一个“显示”。有很多异步模式的在线资源,所以我不会在这里击败那匹死马。