Jump to content
Xtreme .Net Talk

Recommended Posts

Posted (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 by ToniMontana

Greetings,

 

Toni.

Posted

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.

Greetings,

 

Toni.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...