Problem accessing a TextBox control from another class/thread in VB.NET
im trying to access a richtextbox from another class and thread then the ui and i cant seem to get it working. I currently have the sub thats handling the the work inside of a public class and its a sharedsub, im going to be calling it from several different classes and threads but again i cant seem to get it working. the code looks like this.
Public Class SharedSubs
Public Shared Sub console(ByVal message As String)
Dim c As New Form1
If c.consoleBox.Text.Length > 0 Then
If c.consoleBox.Text.Substring(c.consoleBox.Text.Length - 3, 3) = "..." Then
c.consoleBox.AppendText(message)
ElseIf c.consoleBox.Text.Substring(c.consoleBox.Text.Length - 1, 1) = "." Then
c.consoleBox.AppendText(ControlChars.NewLine & timeStamp() & message)
End If
Else
c.consoleBox.AppendText(timeStamp() & message)
End If
End Sub
i would be calling sub us开发者_如何学Pythoning SharedSubs.Console("stringstring")
when this is called from the ui thread it works fine but when its called from anyother thread or class its does nothing, ive confirmed it going thru this code but its not displaying anything in the textbox and its not thru an exception due to delegates either which i figured it would.
Am i doing this completely wrong? some help would be great, thanks.
You can't modify the display of a Winforms UI component from a thread other than the main/UI thread. To update from another thread, check out Control.Invoke's documentation. It has a nice example.
http://msdn.microsoft.com/en-us/library/zyzhdc6b%28v=VS.100%29.aspx
Ideally, use an event, then you can have other things attached to your Textupdate... Eg You might want to display it, and log it ... then you just bind the form and the log to the event.
If you really want to call the method on your form, then you'll need to call it on the proper thread. This can be done 2 ways.
In the class where you are creating the Thread you pass a reference to the Form/Control into the constructor (and therefore that is on the same thread at that point). Store the reference in your class. Then create your Thread. (Don't use the shared so that you are referring to the correct instance)
Delegate sub ConsoleDelegate(byval message as string)
Public Sub console(ByVal message As String)
In your Thread, you then just Invoke the Form.
mForm.Invoke(new ConsoleDelegate(addressof DoSomething), new object(){message})
OR
From your thread you Call the method on your form, and inside the Method on the form.
private Delegate sub ConsoleDelegate(byval message as string)
Public Sub console(ByVal message As String)
If me.InvokeRequired then
me.Invoke(new ConsoleDelegate(addressof DoSomething), new object(){message})
return
end if
'Do the actual work.
end sub
Try adding this code on form load:
Me.CheckForIllegalCrossThreadCalls = False
It should fix the problem
精彩评论