设置特定的文本框以显示登录线程 [英] Set specific textbox to display log on threading
问题描述
我正在创建一个应用程序,以便在一定的时间间隔内将信息连续发送到云服务.当前,有10个设备信息要发送.我正在使用Winform模拟所有要显示的信息数据.我有10个Richtextbox,可将其视为每个设备的事件日志.
每个richtextbox的名称是rtb_dev001,rtb_dev002等.在加载表单时,我已经加载了设备ID.在计时器计时时,我将调用后台工作程序以启动ThreadPool并传递设备信息对象(ID,状态,RTB),其中RTB指示哪个richtexbox将作为附加文本.
目前,我被困在声明如果deviceid ="dev001",我将在函数线程中设置新的RTB并设置字符串"rtb_"& deviceid.现在,这部分失败了.
i''m creating an application to continuous sending information to cloud services in certain interval. currently, there is 10 device information to be send. i''m using winform to simulate all information data to display. i have 10 richtextbox which treat as event log for each device.
name for each richtextbox is rtb_dev001, rtb_dev002 etc. I have load the device ID when form load. At timer tick, I will call background worker to start a ThreadPool and pass the deviceinformation object (ID, State, RTB) where RTB indicated which richtexbox will be appendtext.
Currently I''m stuck at declaring "if deviceid = "dev001", i will set new RTB in a function thread and set a string "rtb_" & deviceid. Now, this part is failed.
<pre lang="VB">
Structure DeviceRecord
Dim Desc As String
Dim State As String
Dim Rtb As RichTextBox
Sub New(ByVal DevDesc As String, ByVal DevState As String, ByVal rtb As RichTextBox)
Me.Desc = DevDesc
Me.State = DevState
Me.Rtb = rtb
End Sub
Sub New(ByVal Files() As DeviceRecord)
For Each f As DeviceRecord In Files
Dim fr As New DeviceRecord(f.Desc, f.State, f.Rtb)
Next
End Sub
End Structure
Private Sub datasender_Load(sender As Object, e As EventArgs) Handles MyBase.Load
bgwWorker1 = New System.ComponentModel.BackgroundWorker
With bgwWorker1
.WorkerReportsProgress = True 'we'll need to report progress
.WorkerSupportsCancellation = True 'allows the user to stop the activity
End With
Dim wslist As slaveinformation.Slave() = ws.GetSlaveList()
If Not (IsNothing(wslist)) Then
f_tbl = New DataTable
f_row = f_tbl.NewRow
For i As Integer = 0 To wslist.Length - 1
Dim deviceid As String = wslist(i).Name
Dim state As StateType = wslist(i).State
Dim name As String = "rtb_" & deviceid.ToString.Replace("-", "").ToLower
Select Case deviceid
Case "dev001"
slavedevice.Add(New DeviceRecord("dev001", state.ToString),rtb_dev001)
Case "dev002"
slavedevice.Add(New DeviceRecord("dev002", state.ToString),rtb_dev002)
Case "dev003"
slavedevice.Add(New DeviceRecord("dev003", state.ToString),rtb_dev003)
Case "dev004"
slavedevice.Add(New DeviceRecord("dev004", state.ToString),rtb_dev004)
Case "dev005"
slavedevice.Add(New DeviceRecord("dev005", state.ToString),rtb_dev005)
Next
End If
InitializeAzureInstance()
End Sub
Private Sub tmrloop_Tick(sender As Object, e As EventArgs) Handles tmrloop.Tick
Try
nowdatetime = DateTime.Now
tmrloop.Stop()
tmrloop.Enabled = False
bgwWorker1.RunWorkerAsync()
Return
Catch ex As Exception
AppendTextBox(rtb_events, "Error timer tick: " & ex.Message.ToString, Color.Red)
End Try
End Sub
Private Sub StartMyWork()
Try
taskstart = DateTime.Now
For i As Integer = 0 To slavedevice.Count - 1
devdata(0) = slavedevice.Item(i).Desc
devdata(1) = slavedevice.Item(i).State
devdata(2) = slavedevice.Item(i).Rtb
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf SubListSelectedSlave), devdata)
Threading.Thread.Sleep(10)
Next
Catch ex As Exception
AppendTextBox(rtb_events, "Error start my work: " & ex.Message.ToString, Color.Red)
End Try
End Sub
Private Sub bgwWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles bgwWorker1.DoWork
Try
If bgwWorker1.CancellationPending Then
e.Cancel = True
Return
End If
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf StartMyWork))
Threading.Thread.Sleep(10)
Catch ex As Exception
AppendTextBox(rtb_events, "Error backgroundworker do its work: " & ex.Message.ToString, Color.Red)
End Try
End Sub
Private Sub bgwWorker1_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles bgwWorker1.RunWorkerCompleted
taskend = DateTime.Now
Dim duration As TimeSpan = taskend - taskstart
AppendTextBox(rtb_events, "Task full completed: " & duration.ToString, Color.Blue)
tmrloop.Enabled = True
tmrloop.Start()
End Sub
Private Async Sub SubListSelectedSlave(ByVal cname As Object)
Try
Dim icnt = 0
Dim startTime As New DateTime()
Dim endTime As New DateTime()
currdate = CInt(Format(nowdatetime, "yyyMMdd"))
currtime = CInt(Format(nowdatetime, "HHmmss"))
startTime = DateTime.Now
Dim matches() As Control
Dim rtb As RichTextBox = New RichTextBox
matches = Me.Controls.Find(CStr(cname(2)), True)
If matches.Length > 0 AndAlso TypeOf matches(0) Is RichTextBox Then
rtb = DirectCast(matches(0), RichTextBox)
End If
Dim ctrl As Control
For Each ctrl In Me.Controls
If (ctrl.GetType.ToString = "System.Windows.Forms.RichTextBox") Then
CType(ctrl, RichTextBox).Text = "All textbox text is the same."
End If
Next
AppendTextBox(rtb, "Showing data:" & CStr(cname(0), Color.LightGreen)
Catch ex As Exception
AppendTextBox(rtb_events, "Error get controller information: " & ex.Message.ToString, Color.Red)
End Try
End Sub
</pre>
我尝试过的事情:
What I have tried:
Dim matches() As Control
Dim rtb As RichTextBox = New RichTextBox
matches = Me.Controls.Find(CStr(cname(2)), True)
If matches.Length > 0 AndAlso TypeOf matches(0) Is RichTextBox Then
rtb = DirectCast(matches(0), RichTextBox)
End If
Dim ctrl As Control
For Each ctrl In Me.Controls
If (ctrl.GetType.ToString = "System.Windows.Forms.RichTextBox") Then
CType(ctrl, RichTextBox).Text = "All textbox text is the same."
End If
Next
推荐答案
Structure DeviceRecord
Dim Desc As String
Dim State As String
Dim Rtb As RichTextBox
Sub New(ByVal DevDesc As String, ByVal DevState As String, ByVal rtb As RichTextBox)
Me.Desc = DevDesc
Me.State = DevState
Me.Rtb = rtb
End Sub
Sub New(ByVal Files() As DeviceRecord) '?
For Each f As DeviceRecord In Files '?
Dim fr As New DeviceRecord(f.Desc, f.State, f.Rtb) '?
Next
End Sub
End Structure
将DeviceRecord实例传递给DeviceRecord的意义是什么?在结构外部创建多个实例时,应使用另一种方法.
What is the point of passing an instance of DeviceRecord to DeviceRecord? You should use another approach when creating multiple instances of the structure, outside of it.
If TypeOf(ctrl) Is RichTextBox Then
DirectCast(ctrl, RichTextBox).Text = "All textbox text is the same."
End If
'Find RTB
For Each ctr In Me.Controls
If (TypeOf(ctr) Is RichtextBox) AndAlso (DirectCast(ctr, RichTextBox).Name.ToLower() = ("rtb_" & deviceID).ToLower()) Then
slavedevice.Add(New DeviceRecord(deviceID), DirectCast(ctr, RichTextBox))
End If
Next
要从其他线程访问控件,必须使用所谓的Delegates.
此示例显示如何更改RichTextBox的Text属性.
To access Controls from a different thread you must use so called Delegates.
This example shows how to change Text Property of RichTextBox.
Delegate Sub DEL_AppendText(ByRef rtb As RichTextBox, ByVal txt As String)
Sub Appendext(ByRef rtb As RichTextBox, ByVal txt As String)
If Me.InvokeRequiered Then
rtb.Invoke(New DEL_AppendText(AddressOf AppendText), rtb, txt)
Else
rtb.AppendText(txt) 'or rtb.Text = txt
End If
End Sub
这篇关于设置特定的文本框以显示登录线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!