Vb.net .net 2010从自定义控件库中调用DoEvents(是的,我想这样做)
我有一个自定义控件的库。现在有一个控件,它看起来像一个面板,当它打开时,我想设置它垂直生长的动画,如下所示:Vb.net .net 2010从自定义控件库中调用DoEvents(是的,我想这样做),vb.net,animation,class-library,doevents,Vb.net,Animation,Class Library,Doevents,我有一个自定义控件的库。现在有一个控件,它看起来像一个面板,当它打开时,我想设置它垂直生长的动画,如下所示: 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,那么动画就不会显示,我只会得到最终高度,而不会得到沿途的视觉反馈 我可以从主Wi
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,但不能在库中调用
我如何才能做到这一点,而不被淹没在深水中?也许您只是缺少了对
系统.Windows.Forms的引用(或导入)
DoEvents
是应用程序
的静态方法,因此您也应该能够从库中调用它
Imports System.Windows.Forms
...
Application.DoEvents()
(您似乎已经知道使用
DoEvents
是一件危险的事情,因此我将跳过通常的讲座。)是的,您应该可以打电话给
System.Windows.Forms.Application.DoEvents()
从您的代码库中。看来你明白DoEvents是个坏主意,所以我不知道你为什么叫它。我猜您已经将其放入了一个覆盖中,如OnVisibleChanged或OnPaint-如果是这种情况,您很可能无法获得所需的结果,因为控件刷新将在这些操作期间暂停
您可能想做的是创建一个单勾号计时器,并在勾号时增加控件的高度-然后在达到最终高度时禁用计时器,或者如果没有,则计划另一个勾号。或者,创建一个计时器,并将上面的循环放在每个刻度上。确保您知道所需的调用和跨线程调用,具体取决于您使用的计时器类型。无法复制
刚刚通过一个简单的设置进行了测试,在程序集中使用UserControl
当UC在循环中调用DoEvents()时,MainForm上的计时器会一直滴答作响
所以:再看看你的问题,它并不是你认为的那样。对不起,但是在这里使用DoEvents是完全不可能安全的。当用户在动画运行时关闭窗体时,不会发生任何好事。它将使用ObjectDisposed异常使程序崩溃。要使DoEvents安全,需要将表单的Enabled属性设置为false,这样用户就不会意外地造成这样的灾难。控件不能合理地将窗体的Enabled属性设置为false,尤其是对于动画
解决方法非常简单,只需使用间隔为15毫秒的计时器。足够快以使动画看起来平滑。你会在我的答案中找到这样做的示例代码。这就是我发现的:计时器,即使间隔很快,也非常慢。我不知道为什么,但动画是非常跳跃的计时器。简化代码:
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循环中,将
Me.Refresh
放置在要调用doevents的位置
For h As Single = 0 To finalHeight Step 0.5
Me.Height = CInt(h)
Me.refresh
Next
Me.Height = finalHeight
@vulkanino:当它位于WinForm项目中时,同样的代码也可以工作?@vulkanino:你确定吗?完全相同的UserControl.vb文件,唯一的区别是它要么位于库中,要么位于主项目中?计时器滴答作响,但动画速度非常慢。这就是我决定使用循环和DoEvents的原因。我在mainform上使用了一个计时器来显示库中的DoEvents可以工作。但是DowEvents仍然是一个非常糟糕的主意。那不是真的。动画运行时,用户无法关闭窗体。用户输入被阻止。计时器工作,但速度很慢。呃,现在被阻塞了,是的。但当你开始打电话给DoEvents时就不行了。哦,15毫秒并不慢。这是每秒60次更新,比你看电影时看到的速度快一倍多。它看起来很慢,因为0.5像素的增量太小了。设为5。顺便说一下,0.5像素的增量是无意义的。
For h As Single = 0 To finalHeight Step 0.5
Me.Height = CInt(h)
Me.refresh
Next
Me.Height = finalHeight