代码之家  ›  专栏  ›  技术社区  ›  Dan Is Fiddling By Firelight Leniency

winforms控件添加到窗体时是否引发事件

  •  8
  • Dan Is Fiddling By Firelight Leniency  · 技术社区  · 14 年前

    我正在做一些定制 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);
        }
    }
    

    事实证明,这比我最初意识到的要困难得多,我想我必须把博卢和迈克·多尔的建议结合起来。问题是当一些 MyControl s直接添加到形式中,在这种情况下,bolu的解决方案工作得很好。其他的则添加到面板中,而不是直接添加到表单中。我想我已经拼凑出了一个涉及Bolu对前一个案例的解决方案,并做了一些修改,以处理由添加的小组引发的事件,而不是 我的控制 在里面,米克负责处理 我的控制 在构造函数完成运行后将添加到面板中。明天早上我得再做一次测试,然后才能确信它能起作用。

    当我尝试在设计器中使用他的建议时,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 回复  |  直到 7 年前
        1
  •  10
  •   Mike Dour    14 年前

    尝试 ParentChanged 事件。

        2
  •  1
  •   Bolu    14 年前
    1. 添加新的 MyForm 中的对象 MyControl

      MyForm pForm;

    2. 通过A 肌样的 参考 我的控制 创建时:

      mycontrol newcontrol=新mycontrol(this);

    3. 然后注册 ControlAdded 您的活动 肌样的 对象

      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);
            }
    
        }
    
        3
  •  -2
  •   Russ Clarke    14 年前

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

    本文介绍了这种方法:

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

    推荐文章