vb.net制作通知表单的动画。螺纹和尺寸问题

vb.net制作通知表单的动画。螺纹和尺寸问题,vb.net,multithreading,forms,Vb.net,Multithreading,Forms,我创建了一个类用作通知窗口(类似于toast通知,它在我们的系统中被禁用)。 我使用一个timer对象来超时关闭表单,并使用backgroundworker来处理它从屏幕底部滑入的动画。出于调试目的,表单只输出自己的大小和屏幕边界 Imports System.ComponentModel Public Class ASNotify Public Sub New(ByVal title As String, ByVal msg As String, ByVal Optional ti

我创建了一个类用作通知窗口(类似于toast通知,它在我们的系统中被禁用)。 我使用一个timer对象来超时关闭表单,并使用backgroundworker来处理它从屏幕底部滑入的动画。出于调试目的,表单只输出自己的大小和屏幕边界

Imports System.ComponentModel

Public Class ASNotify

    Public Sub New(ByVal title As String, ByVal msg As String, ByVal Optional timeout As Integer = 5000)
        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        Me.Text = title
        Me.NotifyMessage.Text = $"{Me.Width}x{Me.Height}{vbCrLf}{My.Computer.Screen.WorkingArea.Size.Width}x{My.Computer.Screen.WorkingArea.Size.Height}"
        TimeoutTimer.Interval = timeout
        TimeoutTimer.Enabled = True
        AnimationWorker.RunWorkerAsync()
    End Sub

    Private Sub AnimationWorker_DoWork(sender As Object, e As DoWorkEventArgs) Handles AnimationWorker.DoWork
        Dim xloc As Integer = My.Computer.Screen.WorkingArea.Size.Width - Me.Width
        Dim yloc As Integer = My.Computer.Screen.WorkingArea.Size.Height

        For x As Integer = 0 To Me.Height
            MoveWindow(xloc, yloc - x)
            Threading.Thread.Sleep(2)
        Next
    End Sub

    Private Sub MoveWindow(xloc As Integer, yloc As Integer)
        If InvokeRequired Then
            Invoke(Sub() MoveWindow(xloc, yloc))
        Else
            Location = New Drawing.Point(xloc, yloc)
        End If
    End Sub

    Private Sub TimeoutTimer_Tick(sender As Object, e As EventArgs) Handles TimeoutTimer.Tick
        Me.Close()
    End Sub
    
End Class
我从另一个表单中调用

Private Sub NotifyUser(ByRef a As Alert.Alert)
    Dim notify As New ASNotify(a.Location, a.Comment, 5000)
    notify.Show()
End Sub
我通过按下表单上的按钮来调用sub,它可以完美地工作……有时

反复触发notify窗口会使其作为屏幕上两种不同大小的窗口之一弹出,尽管显示大小的内容始终为264x81和1920x1040


偶尔我也会遇到一个例外,那就是说‘Location=new Drawing.Point(xloc,yloc)这一行是从一个线程调用的,而不是从创建它的线程调用的,尽管调用了Invoke。

将timer start和animationworker start移动到表单的Load方法,而不是new

Private Sub ASNotify_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    TimeoutTimer.Enabled = True
    AnimationWorker.RunWorkerAsync()
End Sub

你为什么不使用定时器来执行转换呢?无论如何,您正在调用(尝试)UI线程。如果您确实想使用BackgroundWorker,请使用其
DoWorkEventArgs
将表单的高度传递给DoWork处理程序,然后更新其处理程序中的位置:该事件在UI线程中引发,因此无需担心调用(如果需要调用UI线程,请调用
BeginInvoke()
invokererequired
不是必需的)。没有完全解决我的问题,但重新编写以使用begininvoke,并阅读产生的错误,使我找到了解决方案。打电话时,车窗没有完全打开。将动画和计时器移到加载方法,而不是新方法,现在可以工作了。您尝试过该功能吗?从复制vb.net签名并尝试一下。嗯,谢谢。我一定要看一看。