Changing the value of a property from a toolstrip control across threads

I ran across this issue while working on the UI for one of our tools and I found a bunch of code samples to solve the issue for regular controls and vague references (but no samples) as to how to work with this on toolstrip controls (in my case I needed to enable/disable menu items). I won’t go into the details of what it does since there’s a million topics on the subject already but the basics is that you’re declaring a delegate and then changing the property you want through reflection. This is the code for regular controls:

delegate void SetControlValueCallback(Control control, string property, object value);

void SetControlPropertyValue(Control control, string property, object value)

{

       if (control.InvokeRequired)

       {

              SetControlValueCallback callback = new SetControlValueCallback(SetControlPropertyValue);

       control.Invoke(callback, new object[] { control, property, value });

       }

       else

       {

       Type t = control.GetType();

       PropertyInfo p = t.GetProperty(property);

       p.SetValue(control, value, null);

       }

}

The problem with toolstrip controls is that they don’t really inherit from the control class so you can’t call Invoke on them. The trick is to call invoke on the Owner control while still passing the toolstrip control to the callback (if you pass the owner control to the callback you’ll get some funny results like your whole menu bar being disabled…). Here’s the code snippet for that:

delegate void SetToolstripValueCallback(ToolStripItem toolstripItem, string property, object value);

void SetToolstripPropertyValue(ToolStripItem toolstripItem, string property, object value)

{

       if (toolstripItem.Owner.InvokeRequired)

       {

              SetToolstripValueCallback callback = new SetToolstripValueCallback(SetToolstripPropertyValue);

              toolstripItem.Owner.Invoke(callback, new object[] { toolstripItem, property, value });

       }

       else

       {

              Type t = toolstripItem.GetType();

              PropertyInfo p = t.GetProperty(property);

              p.SetValue(toolstripItem, value, null);

       }

}