<Component>.Select() doesn't work...

Fazzyer

Member
Joined
Jul 29, 2005
Messages
16
Programming Experience
5-10
Hi all!

I want to select a component always, when my timer elapses. Unfortunately, this seems not to work. When I select the component in a Button.OnClick-Event, it works. I don't understand this!

VB.NET:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
	TextBox2.Select() 'works
End Sub
 
Private Sub ontimer(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs)
	TextBox2.Select() 'works NOT
End Sub
 
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
	t.Start()
	AddHandler t.Elapsed, AddressOf ontimer
End Sub

Can someone please help me and tell me how to do it right?

Thanx, Fazzyer
 
The problem is your choice of using the System.Timers.Timer class instead of the System.Windows.Forms.Timer class. The System.Timers.Timer is a server-based timer that was designed and optimized for use in multithreaded environments. The System.Timers.Timer class will, by default, call your timer event handler on a worker thread obtained from the common language runtime (CLR) thread pool. This means that the code inside your Elapsed event handler must conform to a golden rule of Win32 programming: an instance of a control should never be accessed from any thread other than the thread that was used to instantiate it. Setting the SynchronizingObject property of the System.Timers.Timer to an instance of a Windows Form (or a control on a Windows Form) will ensure that the code in your Elapsed event handler runs on the same thread on which the SynchronizingObject was instantiated.

All that being said, you can cause your above code to work by inserting the line 't.SynchronizingObject = Me' before the 't.Start()' line in your Load event handler.

I would however suggest using the System.Windows.Forms.Timer class and it's Tick event instead.
 
Another Question...

Hi,

thank you for your quick answer. I think, I understood it. :) So, now I've got another question regarding a similar topic... (the exemple above was only the "simplified" version of my real problem, but I didn't imagine the solution this "difficult").

I'm trying to write a little network-application (server/client) including a chat. All is working except the chat-RichTextBox scrolling automatically to the end: I can neither select nor focus it, because (and this was answered on my first question) the function-call occurs in another thread (I'm using the TcpClient.GetStream.BeginRead-function to receive messages from the server; if a message is coming in, the function including EndRead is always executed in a new thread).

So, again simplified, here is my new question: How can I store an instance-variable, so that it can be accessed through multiple threads?
I have two classes, Form1 and Class1. Form1 creates an instance from Class1 with a copy of itself as parameter. The constructor from Class1 stores this instance of Form1 and creates a new thread, which tries to set the focus on Form1.TextBox1 after one second... but it doesn't work. Here's the code:

VB.NET:
[color=blue]Public Class[/color] Form1 [color=red]' Just TextBox1 and Button1...[/color]
 
[color=blue]Private[/color] C [color=blue]As[/color] Class1
 
[color=blue]Private Sub[/color] Button1_Click(...) [color=blue]Handles[/color] Button1.Click
C = [color=blue]New[/color] Class1([color=blue]Me[/color])
TextBox1.Text = "C created"
[color=blue]End Sub[/color]
 
[color=blue]End Class[/color]
 
[color=red]' -------------------[/color]
 
[color=blue]Public Class Class1[/color]
 
[color=blue]Private Shared[/color] MyForm1 [color=blue]As[/color] Form1 [color=red]' -- doesn't matter if shared or not[/color]
[color=blue]Private[/color] TThread [color=blue]As[/color] Threading.Thread
 
[color=blue]Public Sub New[/color]([color=blue]ByRef [/color]FForm1 [color=blue]As[/color] Form1)
MyForm1 = FForm1
MsgBox(MyForm1.TextBox1.Focus()) [color=red]' TRUE[/color]
TThread = [color=blue]New[/color] Threading.Thread([color=blue]AddressOf[/color] TestMe)
TThread.Start()
[color=blue]End Sub[/color]
 
[color=blue]Public Sub[/color] TestMe()
Threading.Thread.CurrentThread.Sleep(1000)
MsgBox(MyForm1.TextBox1.Focus()) [color=red]' FALSE[/color]
[color=blue]End Sub[/color]
 
[color=blue]End Class[/color]

Can anyone please help me? Any hint is welcome... :)

Thanx, Fazzyer
 
I haven't read your post carefully but you might be interested in the ScrollToCaret method of the RichTextBox. If you set the SelectionStart property to the end of the Text and call ScrollToCaret the RTB will scroll to the end whether it is focused or not.
 
Re

Hi,

thanks for the answer, I knew the ScrollToCaret-Method already. The problem is that I can't focus the richtextbox (or the textbox in the above example, it's the same problem), and without focus, I can't scroll to caret.

Thanx, Fazzyer
 
Sorry, I should have tested before posting. I've done it with a regular TextBox before and you don't need to focus one of those so I assumed the RTB would be the same.
 
Back
Top