0

我有一个自定义控件的库。现在有一个看起来像面板的控件,当它打开时,我想为它的垂直增长设置动画,如下所示:

For h As Single = 0 To finalHeight Step 0.5
    Me.Height = CInt(h)
    '  HERE I WANT TO CALL DoEvents'
Next
Me.Height = finalHeight 

如果我不在循环中调用 DoEvents 则不会显示动画,我只会得到最终高度而没有沿途的视觉反馈。

我可以从我的主 WinForm 项目中调用 DoEvents,但不能在库中调用。

我怎样才能做到这一点,而不淹没在深水里?

4

6 回答 6

3

对不起,但在这里使用 DoEvents 是完全不可能的。当您的动画正在播放时用户关闭表单时,不会发生任何好事。它将使用 ObjectDisposed 异常使程序崩溃。使 DoEvents 安全需要将表单的 Enabled 属性设置为 false,这样用户就不会意外地导致此类事故。控件无法合理地将表单的Enabled 属性设置为 false,尤其是对于动画而言更是如此。

解决方法很简单,只需使用间隔为 15 毫秒的计时器。足够快以使动画看起来流畅。您将在我在此线程的回答中找到执行此操作的示例代码。

于 2010-09-21T13:04:44.090 回答
2

是的,你应该可以打电话

System.Windows.Forms.Application.DoEvents()

从您的代码库中。看来您知道 DoEvents 是一个坏主意,所以我不确定您为什么要调用它。我猜你已经把它放在像 OnVisibleChanged 或 OnPaint 这样的覆盖中 - 如果是这种情况,你很可能不会得到你想要的结果,因为在这些操作期间控件刷新将被暂停。

您可能想要做的是创建一个单滴答计时器,并在滴答时增加控件的高度 - 然后在达到 finalheight 时禁用计时器,或者如果没有安排另一个滴答。或者,创建一个计时器并在每个滴答时将上述循环放入其中。确保您了解InvokeRequired和跨线程调用,具体取决于您使用的计时器类型。

于 2010-09-21T12:38:32.330 回答
2

也许您只是缺少对(或导入)的引用System.Windows.FormsDoEvents是 的静态方法Application,因此您也应该能够从库中调用它。

Imports System.Windows.Forms

...

    Application.DoEvents()

(您似乎已经知道使用DoEvents是一件危险的事情,所以我将跳过这里通常的讲座。)

于 2010-09-21T12:12:28.370 回答
1

无法重现。

刚刚用一个简单的设置进行了测试,UserControl 在一个程序集中。

当 UC 在循环中调用 DoEvents() 时,MainForm 上的计时器一直在计时。

所以:再次寻找你的问题,它不是你认为的问题。

于 2010-09-21T12:42:34.003 回答
0

在你原来的 for 循环中,Me.Refresh你想调用 doevents 的地方。

For h As Single = 0 To finalHeight Step 0.5
    Me.Height = CInt(h)
    Me.refresh
Next
Me.Height = finalHeight
于 2012-01-04T17:34:01.103 回答
-1

这就是我发现的:计时器,即使间隔很快,也很慢。我不知道为什么,但是动画与计时器非常跳动。简化代码:

 rolex = New Timer()
 rolex.Interval = 150
 AddHandler rolex.Tick,
            Sub(sender As Object, e As EventArgs)

                Me.Height += 5

                If Me.Height < finalHeight Then Exit Sub

                rolex.Stop()
                rolex = Nothing

                Me.Height = finalHeight 
            End Sub
 rolex.Start()

没有计时器,我使用循环:

For i As Single = 0 To finalHeight Step 0.5
            Height = CInt(i)
            Application.DoEvents()
Next
Height = finalHeight 

它现在可以工作,但问题是动画速度太多取决于执行循环的机器。出于这个原因,我想使用计时器,但正如我所说的那样太慢了。

有什么提示吗?

于 2010-09-21T13:51:28.160 回答