好的,所以我正在尝试创建一个小的VB.NET程序,它应用并监视另一个应用程序中的值,我遇到了一个我似乎无法找到答案的障碍。
我想要一个单独的表格,或者同一表格的一部分,从其他程序拉出值[不是问题]分析它们并显示它们的状态。问题是,每当我使用表单来实现这一点时,我发现这个更改文本所在的窗口在功能上对用户没有响应,鼠标滚轮旋转,并且无法访问位于该表单上的任何控件(其他按钮,最小化关闭,或点击将其带到前面/调整窗口大小的能力)。
我目前正在使用一个后台工作程序,它有一个显示表单的dowork方法,然后更新其上的文本标签,然后在循环中刷新表单。可以通过更改公共共享变量来取消此循环。我可以清楚地看到文本正在使用值进行更新,但是表单没有响应。
这有什么办法吗?我希望表单能够像常规应用程序窗口一样运行,并且在显示真实时可以调整大小/可关闭。
以下是我的代码示例,其中包含可能存在损害的位或其他编辑内容:
Imports System.ComponentModel
Imports System.Linq
Public Class Form1
Public Shared notbroken = 1 'Break the killer loop
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Ok Button
Button1.Hide() 'Stop user from clicking the button again.
Dim choice
'show which button is selected in each case
Dim regenType As RadioButton = GroupBox1.Controls.OfType(Of RadioButton).FirstOrDefault(Function(r) r.Checked = True)
Dim regenVariant As RadioButton = moving.Controls.OfType(Of RadioButton).FirstOrDefault(Function(r) r.Checked = True)
'Assigns a number from the selection to these once the ok button is pressed.
mainmethod(choice)
End Sub
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
notbroken = 0
If BackgroundWorker1.WorkerSupportsCancellation = True Then
BackgroundWorker1.CancelAsync()
End If
End Sub
Private Sub mainmethod(regenchoice As Integer)
'Main Logic
'Project.Online = True 'TODO - Uncomment
AssignHandles()
CollectOrRestore("collect") 'Collect values to restore upon reopen
'Recorder.Start
RunRegen(regenchoice)
If Not BackgroundWorker1.IsBusy = True Then
BackgroundWorker1.RunWorkerAsync()
End If
'SaveRecording
'CloseProj()
End Sub
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Form3.Show()
Do While Form1.notbroken
Form3.Label1.Text = DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss")
' Sample of how Im reporting status
Form3.Label2.Text = "Text String: " & statusOfTextStringCheck()
Form3.Refresh()
Loop
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
If e.Cancelled = True Then
Label1.Text = "Canceled!"
Refresh()
Threading.Thread.Sleep(2000)
Label1.Text = "IN CASE OF EMERGENCY: "
Form3.Close()
Button1.Show()
Return
ElseIf e.Error IsNot Nothing Then
Label1.Text = "Error: " & e.Error.Message
Refresh()
Threading.Thread.Sleep(2000)
Label1.Text = "IN CASE OF EMERGENCY:"
Form3.Close()
Button1.Show()
Return
Else
Label1.Text = "Done!"
Refresh()
Threading.Thread.Sleep(2000)
Label1.Text = "In Case Of EMERGENCY:" & e.Result
Form3.Close()
Button1.Show()
Return
End If
End Sub
Private Sub CloseProj()
Dim x = MsgBox("Are you sure you want to close the project?" & vbCrLf & ":Initial Values will be restored.", 65, "ClearVision")
If x = 2 Then Return
CollectOrRestore("restore") 'Restore Initial Values
release()
Me.Close()
End Sub
End Class
答案 0 :(得分:0)
这里我汇总了一个如何在表单中使用Background worker的快速示例。第一条规则不是在后台工作程序中设置任何UI元素,而是通过Background工作程序的ProgressChanged事件发送更改,并在UI线程上进行更改。
示例代码:
Public Class Form1
Private Sub cmdStart_Click(sender As Object, e As EventArgs) Handles cmdStart.Click
If Not BackgroundWorker1.IsBusy Then
BackgroundWorker1.WorkerReportsProgress = True
BackgroundWorker1.WorkerSupportsCancellation = True
BackgroundWorker1.RunWorkerAsync()
End If
End Sub
Private Sub cmdEnd_Click(sender As Object, e As EventArgs) Handles cmdEnd.Click
_bCancel = True
End Sub
Private _bCancel As Boolean = False
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim iIteration As Long = 0
Do Until _bCancel
iIteration += 1
Dim sTime As String = DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss")
Dim sStatus As String = "Iteration Status " & iIteration.ToString()
BackgroundWorker1.ReportProgress(0, New WorkProgress(sTime, sStatus))
Threading.Thread.Sleep(50)
Loop
End Sub
Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
If Me.InvokeRequired Then
Dim act As Action(Of System.ComponentModel.ProgressChangedEventArgs) = AddressOf HandleProgressChanged
Me.Invoke(act, e)
Else
HandleProgressChanged(e)
End If
End Sub
Private Sub HandleProgressChanged(e As System.ComponentModel.ProgressChangedEventArgs)
Dim progress As WorkProgress = DirectCast(e.UserState, WorkProgress)
lblTime.Text = progress.TimeText
lblStatus.Text = progress.Status
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
End Sub
Public Class WorkProgress
Public TimeText As String
Public Status As String
Public Sub New(sTimeText As String, sStatus As String)
TimeText = sTimeText
Status = sStatus
End Sub
End Class
End Class