将Winforms控件添加到表单时是否会引发事件

时间:2010-11-23 16:31:14

标签: c# winforms events custom-controls

我正在研究一些自定义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
}

3 个答案:

答案 0 :(得分:10)

尝试ParentChanged事件。

答案 1 :(得分:1)

  1. MyForm

    中添加新的MyControl对象

    MyForm pForm;

  2. 在创建时将MyForm引用传递给MyControl

    MyControl newControl = new MyControl(this);

  3. 然后注册ControlAdded对象的MyForm事件

    pForm.ControlAdded+=new ControlEventHandler(pForm_ControlAdded);

  4. 根据您的代码,它应该类似于:

    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)

为什么不在MyControl中实现自定义事件?

本文解释了该方法:

http://ondotnet.com/pub/a/dotnet/2002/04/15/events.html