2017-08-03 163 views
0

我试图在VB.Net的Windows窗体上动画两个按钮的运动。窗体从主窗体中加载ShowDialog()。我有以下代码:动画按钮运动

Private Sub MoveButtons(sender As Object, e As EventArgs) Handles picLogo.Click 
    Dim SLoc As Point = btnSearch.Location 
    Dim CLoc As Point = btnCancel.Location 

    txtSearch.Enabled = False 
    txtSearch.Visible = False 
    btnSearch.Text = "Add" 

    For idx As Integer = 1 To 36 
     SLoc.Y -= 1 
     btnSearch.Location = SLoc 
     CLoc.Y -= 1 
     btnCancel.Location = CLoc 
     Thread.Sleep(5) 
    Next 
End Sub 

我最初的代码它使用Top财产,但结果是一样的。取消按钮按预期向上滑动,但搜索/添加按钮从下往上消失,然后跳到正确的位置。不管我是否更改按钮文本,都会发生这种情况。除了明显的LocationText属性之外,两个按钮是相同的,但取消按钮的DialogResult设置为DialogResult.Cancel

Form screenshots

+0

讨厌这样说,但...把'Application.DoEvents()''之前Thread.sleep代码(5)' – djv

+0

不过说真的,没有。看到我的回答 – djv

回答

1

你是不是给UI任何时间来正确进行自我更新。尽管Thread.Sleep(5)对您的循环时间至关重要,但它也将UI线程置于睡眠状态。你不想这样做。

因此,一个简单但不知情的修复方法是将Application.DoEvents()放入循环中。这将允许UI自行更新。这应该使你的代码工作...

... 
Application.DoEvents() 
Thread.Sleep(5) 

但如果这种类型的东西做的话,你会发现你的UI减慢。它会给应用程序带来不好的感觉。你永远不想让UI线程进入睡眠状态。

你应该做的是从UI中取出所有非UI的东西。你可以创建一个线程并把它放在那里。但是,在线程内部,您需要将任何UI调用回Invoke。以下是我

Private Sub MoveButtons(sender As Object, e As EventArgs) Handles picLogo.Click 
    txtSearch.Enabled = False 
    txtSearch.Visible = False 
    btnSearch.Text = "Add" 
    Dim moveThread As New System.Threading.Thread(AddressOf moveButtonsSub) 
    moveThread.Start() 
End Sub 

Private Sub moveButtonsSub() 
    Dim SLoc As Point = btnSearch.Location 
    Dim CLoc As Point = btnCancel.Location 
    For idx As Integer = 1 To 36 
     SLoc.Y -= 1 
     CLoc.Y -= 1 
     Me.Invoke(
      Sub() 
       btnSearch.Location = SLoc 
       btnCancel.Location = CLoc 
      End Sub) 
     Thread.Sleep(5) 
    Next 
End Sub 
+0

太棒了!我不确定你的意思是“UI外的非UI内容”(我会学习!),但你的解决方案完美无缺。然而,我在'Sub()'里面移动了'For-Next'循环,然后回到使用'Top'属性。 – alanlittle

+0

Windows窗体应用程序开始在UI线程上运行(简单的解释)。但是如果你有一个以上的核心cpu,你应该在UI线程上做最少的处理。您可以通过产生其他非UI线程来完成此任务,您将在其中执行计算等。但是,您无法从这些非UI线程访问UI元素,即控件。所以你必须调用任何访问UI线程上的控件的代码(Control.Invoke)。请参阅[this](https://docs.microsoft.com/en-us/dotnet/framework/winforms/controls/how-to-make-thread-safe-calls-to-windows-forms-controls)了解更多信息。 – djv

+0

好吧,我明白了。有趣。这给了我一些其他应用程序的思考。谢谢。 – alanlittle