做了一个容器控件,控件上放置了三个panel(pnlLeft,pnlContent,pnlRight),pnlLeft和pnlRight只做装饰用,而pnlContent做为实际的容器
但是当将控件拖放到容器控件上时默认是以容器控件为parent的,我想实现将控件拖放到容器控件上时自动将其parent设置为pnlContent
方法1
        protected override void OnControlAdded(ControlEventArgs e)
        {
            base.OnControlAdded(e);
            e.Control.Parent=pnlContent;
        }
结果提示错误:
进行了循环控件引用。控件不能属于自身或成为自身的父级。 
方法2(利用控件设计器)
    public class BlendUIDesigner : ParentControlDesigner
    {
        public override void Initialize(IComponent component)
        {
            base.Initialize(component);            
            IComponentChangeService c = (IComponentChangeService)this.GetService(typeof(IComponentChangeService));
            c.ComponentAdded+=new ComponentEventHandler(OnComponentAdded);
        }
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            IComponentChangeService c = (IComponentChangeService)this.GetService(typeof(IComponentChangeService));
            c.ComponentAdded-= new ComponentEventHandler(OnComponentAdded);
        }
        private void OnComponentAdded(object sender, ComponentEventArgs e)
        {
            IDesignerHost h = (IDesignerHost)this.GetService(typeof(IDesignerHost));
            DesignerTransaction t = h.CreateTransaction();
            System.Windows.Forms.Control c = (System.Windows.Forms.Control)e.Component;
            ((BlendUI)Control).Controls.Remove(c);
            c.Parent = ((BlendUI)Control).Panels[0];
            ((BlendUI)Control).Panels[0].Controls.Add(c);
            t.Commit();
            ((BlendUI)Control).Panels[0].Invalidate();
        }
    }
结果没有错误了,但是没有效果,放到容器里的控件仍然没有改变parent

解决方案 »

  1.   

    我试过了,第一个方法,因为你重写了OnControlAdded事件,所以当你往自己控件中加入pnlContent时,这个事件会被触发,所以产生第一个错误。
    第二种方法,虽然你重写了设计器,但是当你往你的容器控件中加入控件时,你临时改变它的容器,导致设计器无法确定当前选中的控件
    我建议把pnlContent公开出来,即调用设计器的Designer文件生成pnlContent,方法如下:
    IDesignerHost host = (IDesignerHost)Site.GetService(typeof(IDesignerHost));
    Panel c = host.CreateComponent(Panel, "pnlContent") as Panel;
    c.Parent =  this;
      

  2.   

    -_-!!! 我对题意的理解是:protected override void OnControlAdded(ControlEventArgs e) 
    {
        base.OnControlAdded(e);
        
        if (e.Control.Parent != null)
        {
            base.Controls.Add(e.Control.Parent);
        }
    }
      

  3.   

    protected override void OnControlAdded(ControlEventArgs e) 
    {
        if (e.Control.Parent != null)
        {
            base.Controls.Add(e.Control.Parent);
        }
        
        base.OnControlAdded(e);
    }
      

  4.   

    非常感谢cpw999cn 的帮助,他的方法可行,给我提供了另一种实现方法
            protected override void OnCreateControl()
            {
                base.OnCreateControl();
                if (DesignMode)
                {
                    IDesignerHost host = (IDesignerHost)Site.GetService(typeof(IDesignerHost));
                    Panel c = host.CreateComponent(typeof(Panel), "pnlContent") as Panel;
                    c.Parent = this;
                }
            }
    这样在设计控件时会将pnlContent暴露出来,也就是在控件中可以选取到pnlContent控件了,这样就可以直接把控件放置到pnlContent中了,不过我最初的想法肯定是可以实现的,大家再帮忙想想有没有什么好办法呢,也就是不暴露pnlContent控件,直接用代码将放到容器中的控件的父对象指定为pnlContent