I have a project that does exactly what you want.
It's true, when updating anything on a Control, you have to Invoke() to the UI thread like so:
protected AutoResetEvent m_Update = new AutoResetEvent(true);
//Called from a background thread
public virtual void ExpandRootItems()
{
m_Update.WaitOne();
try
{
if (m_TreeView.InvokeRequired)
{
MethodInvoker d = new MethodInvoker(ExpandRootItemsThreadSafe);
m_TreeView.Invoke(d);
}
else
ExpandRootItemsThreadSafe();
}
finally
{
m_Update.Set();
}
}
private void ExpandRootItemsThreadSafe()
{
m_TreeView.BeginUpdate();
foreach (TreeNode node in m_TreeView.Nodes)
{
node.Expand();
}
m_TreeView.EndUpdate();
}
As for the dynamic Control updating, implement everything as one main control Like a UserControl and then Add and remove at your will. You should call Dispose() on it after removing it from the parent control. Also, Event Handlers should be removed in the Dispose calls, otherwise thing accumulate in the form.
To Add one:
public delegate void AddControlDelegate(Control i_Control);
[...]
System.Windows.Forms.Control control = mgr.GetControl();
if(control!= null)
{
if(m_Panel.InvokeRequired)
{
AddControlDelegate addDelegate = new AddControlDelegate(m_Panel.Controls.Add);
m_Panel.Invoke(addDelegate, new object[]{control});
}
else
m_Panel.Controls.Add(control);
}
To remove one:
System.Windows.Forms.Control control = mgr.GetControl();
m_Panel.Controls.Remove(control);
control.Dispose();
also, if you are going to launch a thread, the constructor probably isn't the best place. A better place is in the Load event for a form or control. The Load event is fired after the control is created.