setting grid source within thread? Compiler error...

  • Thread starter Thread starter VM
  • Start date Start date
V

VM

In the thread, I create a tableX and fill it with data. When I set the
grid's source to this tableX, I get a compiler error "Controls created on
one thread cannot be parented to a control on a different thread". I think
this occurs because the grid wasn't created during the thread. How would I
be able to set its datasource from within the thread?

Thanks again.
 
Hi VM,

VM said:
In the thread, I create a tableX and fill it with data. When I set the
grid's source to this tableX, I get a compiler error "Controls created on
one thread cannot be parented to a control on a different thread". I think
this occurs because the grid wasn't created during the thread. How would I
be able to set its datasource from within the thread?

Thanks again.

Your diagnosis is correct. Basically, you should only call methods or
get and set properties of forms or controls from the thread that created the
form or control. Usually you don't get such a nice explicit error, just
flakey or unstable behavior. The work-around is:

1. Create a method that will set the property on the control.
2. Create a delegate object that references the method.
3. Call Control.Invoke on the form or control, passing the delegate
object along with any necessary parameters.

An example (assumes code is within a form):

...
private delegate void SetGridDataSourceHandler(object dataSource);

private void SetGridDataSource(object dataSource)
{
if (this.InvokeRequired)
{
SetGridDataSourceHandler handler =
new SetGridDataSourceHandler(this.SetGridDataSource);

this.Invoke(handler, new object[]{dataSource});
}
else
{
this.dataGrid1.DataSource = dataSource;
}
}
...

DISCLAIMER: The above code is off-the-top-of-my-head and may contain
syntax or other obvious errors.

Regards,
Daniel
 
Thanks for the help. It worked great.

Daniel Pratt said:
Hi VM,

VM said:
In the thread, I create a tableX and fill it with data. When I set the
grid's source to this tableX, I get a compiler error "Controls created on
one thread cannot be parented to a control on a different thread". I think
this occurs because the grid wasn't created during the thread. How would I
be able to set its datasource from within the thread?

Thanks again.

Your diagnosis is correct. Basically, you should only call methods or
get and set properties of forms or controls from the thread that created the
form or control. Usually you don't get such a nice explicit error, just
flakey or unstable behavior. The work-around is:

1. Create a method that will set the property on the control.
2. Create a delegate object that references the method.
3. Call Control.Invoke on the form or control, passing the delegate
object along with any necessary parameters.

An example (assumes code is within a form):

...
private delegate void SetGridDataSourceHandler(object dataSource);

private void SetGridDataSource(object dataSource)
{
if (this.InvokeRequired)
{
SetGridDataSourceHandler handler =
new SetGridDataSourceHandler(this.SetGridDataSource);

this.Invoke(handler, new object[]{dataSource});
}
else
{
this.dataGrid1.DataSource = dataSource;
}
}
...

DISCLAIMER: The above code is off-the-top-of-my-head and may contain
syntax or other obvious errors.

Regards,
Daniel
 
One last question,
If I want to use this functionality in another class in the same
application, what namespaces would I need to add? In another class in this
same application (but abother project), it doesn't recognize this.Invoke.

Thanks agaim.

Daniel Pratt said:
Hi VM,

VM said:
In the thread, I create a tableX and fill it with data. When I set the
grid's source to this tableX, I get a compiler error "Controls created on
one thread cannot be parented to a control on a different thread". I think
this occurs because the grid wasn't created during the thread. How would I
be able to set its datasource from within the thread?

Thanks again.

Your diagnosis is correct. Basically, you should only call methods or
get and set properties of forms or controls from the thread that created the
form or control. Usually you don't get such a nice explicit error, just
flakey or unstable behavior. The work-around is:

1. Create a method that will set the property on the control.
2. Create a delegate object that references the method.
3. Call Control.Invoke on the form or control, passing the delegate
object along with any necessary parameters.

An example (assumes code is within a form):

...
private delegate void SetGridDataSourceHandler(object dataSource);

private void SetGridDataSource(object dataSource)
{
if (this.InvokeRequired)
{
SetGridDataSourceHandler handler =
new SetGridDataSourceHandler(this.SetGridDataSource);

this.Invoke(handler, new object[]{dataSource});
}
else
{
this.dataGrid1.DataSource = dataSource;
}
}
...

DISCLAIMER: The above code is off-the-top-of-my-head and may contain
syntax or other obvious errors.

Regards,
Daniel
 
Hi VM,

VM said:
One last question,
If I want to use this functionality in another class in the same
application, what namespaces would I need to add? In another class in this
same application (but abother project), it doesn't recognize this.Invoke.

Thanks agaim.

Forgive me if I misunderstand your question, but Invoke is a public
method of the System.Windows.Forms.Control class (System.Windows.Forms.Form
inherits System.Windows.Control). As such, you could call it from a
reference to a control or form.

Regards,
Daniel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top