I'm working on some custom Control
classes and need to do some initialization on them which is dependent on them being added to a form. Is there an event that fires when this happens?
I think this sample should be sufficient to show what I'm trying to do:
public interface IMyForm
{
ISomeObject SomeObject {get; set; }
}
class MyForm : IMyForm
{
//eg InitializeComponent() as well as several others called at later points
private MethodThatAddsAControl()
{
MyControl newControl = new MyControl();
//other initialization as needed
//does this raise an event in MyControl I can use to call
//InitializationAfterBeingAddedToForm()?
this.Controls.Add(newControl);
}
}
class MyControl : Control
{
InitializationAfterBeingAddedToForm()
{
//can't be done in the constructor because at that point FindForm() will return null
(FindForm() as IMyForm).SomeObject.AnEvent += new EventHandler(SomeObject_AnEvent);
}
}
This is turning out to be more difficult than I initially realized, and I think I'm going to have to combine the suggestions from Bolu and Mike Dour. The problem is that while some MyControl
s are added directly to the form in which case Bolu's solution works perfectly. Others are added to panels instead of being added directly to the form. I think I've cobbled together a solution involving Bolu's solution for the former case with a few modifications to handle the case where the event is being raised by the panel being added, not the MyControl
within it, and Mikes to handle the case of MyControl
s being added to the panel after the constructor has finished running. I'll have to test this more tomorrow morning before I feel confident that it worked.
Error message requested by Bolu when I try using his suggestion in the designer:
Failed to create component 'MyControl'. The error message follows:
'System.MissingMethodException: Constructor on type 'MyNamespace.MyControl' not found.
at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
at System.ComponentModel.Design.DesignSurface.CreateInstance(Type type)
at Microsoft.VisualStudio.Design.VSDesignSurface.CreateInstance(Type type)
at System.ComponentModel.Design.DesignerHost.System.ComponentModel.Design.IDesignerHost.CreateComponent(Type componentType, String name)
at System.ComponentModel.Design.DesignerHost.System.ComponentModel.Design.IDesignerHost.CreateComponent(Type componentType)
at System.Drawing.Design.ToolboxItem.CreateComponentsCore(IDesignerHost host)
at System.Drawing.Design.ToolboxItem.CreateComponentsCore(IDesignerHost host, IDictionary defaultValues)
...'
And the constructors in place when I got the error.
public MyControl(Form parent)
{
_parent = parent as IMyForm;
parent.ControlAdded += new ControlEventHandler(parent_ControlAdded);
Initialize(); //does rest of initialization
}
public TimelineControl(Form parent, Panel container)
{
_parent = parent as IMyForm;
container.ControlAdded += new ControlEventHandler(parent_ControlAdded);
Initialize(); //does rest of initialization
}
Try the ParentChanged
event.
add a new MyForm
object in MyControl
MyForm pForm;
pass a MyForm
reference to MyControl
when create it:
MyControl newControl = new MyControl(this);
then register ControlAdded
event of your MyForm
object
pForm.ControlAdded+=new ControlEventHandler(pForm_ControlAdded);
Based on your code, it should looks something like:
class MyForm : IMyForm
{
private MethodThatAddsAControl() //includes includes InitializeComponent as well as several others called at later
{
MyControl newControl = new MyControl(this);
//other initialization as needed
this.Controls.Add(newControl); //this will raise MyControl ::pForm_ControlAdded
}
}
class MyControl : Control
{
Myform pForm;
public MyControl(MyForm ff)
{
InitializeComponent();
pForm=ff;
pForm.ControlAdded+=new ControlEventHandler(pForm_ControlAdded);
}
}
EDIT: for the MyControl you want add to a panel, just pass the panel's reference to MyControl:
class MyForm : IMyForm
{
private MethodThatAddsAControl() //includes includes InitializeComponent as well as several others called at later
{
//create a MyControl object and add it to MyForm
MyControl newControl = new MyControl(this);
//other initialization as needed
this.Controls.Add(newControl); //this will raise MyControl::pForm_ControlAdded
//create a MyControl object and add it to MyPanel1
MyControl newControl = new MyControl(MyPanel1); //pass panel reference
MyPanel1.Controls.Add(newControl); //this will raise MyControl::pPanel_ControlAdded
}
}
class MyControl : Control
{
//// for control added to Form
Myform pForm;
public MyControl(MyForm ff)
{
InitializeComponent();
pForm=ff;
pForm.ControlAdded+=new ControlEventHandler(pForm_ControlAdded);
}
///now for control added to panel
MyPanel pPanel;
public MyControl(MyPanel pp)
{
InitializeComponent();
pPanel=pp;
pPanel.ControlAdded+=new ControlEventHandler(pPanel_ControlAdded);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With