我正在研究一些自定义Control
类,需要对它们进行一些初始化,这取决于它们是否被添加到表单中。发生这种情况时会发生事件吗?
我认为这个样本应足以显示我正在尝试做的事情:
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);
}
}
这比我最初意识到的要困难得多,我想我将不得不结合Bolu和Mike Dour的建议。问题在于,虽然一些MyControl
被直接添加到表单中,但在这种情况下,Bolu的解决方案可以完美地运行。其他人被添加到面板而不是直接添加到表单。我想我已经拼凑了一个解决方案,涉及Bolu的前一种情况的解决方案,并进行了一些修改,以处理被添加的面板引发事件的情况,而不是其中的MyControl
,以及要处理的Mikes在构造函数运行完毕后将MyControl
s添加到面板中的情况。我必须在明天早上对此进行更多测试,然后才能确信它有效。
当我尝试在设计师中使用他的建议时,Bolu请求的错误消息:
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)
...'
当我收到错误时,构造函数到位了。
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
}
答案 0 :(得分:10)
尝试ParentChanged
事件。
答案 1 :(得分:1)
在MyForm
MyControl
对象
MyForm pForm;
在创建时将MyForm
引用传递给MyControl
:
MyControl newControl = new MyControl(this);
然后注册ControlAdded
对象的MyForm
事件
pForm.ControlAdded+=new ControlEventHandler(pForm_ControlAdded);
根据您的代码,它应该类似于:
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);
}
}
修改强> 对于你想要添加到面板的MyControl,只需将面板的引用传递给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);
}
}
答案 2 :(得分:-2)