ToniMontana Posted July 28, 2004 Posted July 28, 2004 (edited) Hi, I have a mainform with a panel in it. In this panel I added a UserControl with panel.Controls.Add(UserControl), which is dynamically loaded from my "plug-in".dll. In the UserControl I implemented a mechanism, with which I can send data to display. Every time, the UserControl gets data, it will get the data-object via a data-changed-event. The UserControl can then retrieve the data from the event-object. With this data comes state-information for the controls too. E.g. in the UserControl are several buttons and a textbox. If I send data to set the focus to the textbox, nothing happens! BUT: If I use the same code in a "button-click"-method, I can put the focus to the textbox! Why is it a difference??? And how can I switch the focus to the textbox on receiving a data-event??? Here is some code: The following code will be called after a data event happened: setFocusSuccessful = this.timerTextBox.Focus(); Debug.WriteLine("<this.timerTextBox.Focus()> called: " + setFocusSuccessful.ToString()); The output is: false This code is in the button-click-method: setFocusSuccessful = this.timerTextBox.Focus(); Debug.WriteLine("<this.timerTextBox.Focus()> called: " + setFocusSuccessful.ToString()); The output is: true Yes, you are right, it is the same code in both cases. So there must be a difference if I call the code from the button-click-method! The question is now: What happens additionally in this method, what code is run from the .NET-framework in a button-click-method which the user doesnt know??? Edited July 28, 2004 by ToniMontana Quote Greetings, Toni.
ToniMontana Posted July 30, 2004 Author Posted July 30, 2004 Hi again, I found the solution of the problem and will describe it here for you: The event, which gives the userControl its data and should also switch the focus of a control was generated by my data-receive-thread, which is not the UI-thread!!! This cannot work, but some action do work: I could set the background color of a control or set a control to enabled/disabled but only the setting of the focus didn't work! So, I changed the code so that the data-receiving-thread calls the data-update of the form via Invoke() and a delegate and now it works! Here a schema for correct code to update a form initiated from another thread: if (this.InvokeRequired) { this.BeginInvoke(new DelegateUpdateForm(this.UpdateForm), new object[] { message } ); } else { UpdateForm(message); } info from MSDN: Controls in Windows Forms are bound to a specific thread and are not thread safe. Therefore, if you are calling a control's method from a different thread, you must use one of the control's invoke methods to marshal the call to the proper thread. This property can be used to determine if you must call an invoke method, which can be useful if you do not know what thread owns a control. There are four methods on a control that are safe to call from any thread: Invoke, BeginInvoke, EndInvoke and CreateGraphics. For all other method calls, you should use one of these invoke methods when calling from a different thread. Windows Forms uses the single-threaded apartment (STA) model because Windows Forms is based on native Win32 windows that are inherently apartment-threaded. The STA model implies that a window can be created on any thread, but it cannot switch threads once created, and all function calls to it must occur on its creation thread. Outside Windows Forms, classes in the .NET Framework use the free threading model. Quote Greetings, Toni.
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.