Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net .net 2010从自定义控件库中调用DoEvents(是的,我想这样做)_Vb.net_Animation_Class Library_Doevents - Fatal编程技术网

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