做了一个容器控件,控件上放置了三个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
但是当将控件拖放到容器控件上时默认是以容器控件为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
第二种方法,虽然你重写了设计器,但是当你往你的容器控件中加入控件时,你临时改变它的容器,导致设计器无法确定当前选中的控件
我建议把pnlContent公开出来,即调用设计器的Designer文件生成pnlContent,方法如下:
IDesignerHost host = (IDesignerHost)Site.GetService(typeof(IDesignerHost));
Panel c = host.CreateComponent(Panel, "pnlContent") as Panel;
c.Parent = this;
{
base.OnControlAdded(e);
if (e.Control.Parent != null)
{
base.Controls.Add(e.Control.Parent);
}
}
{
if (e.Control.Parent != null)
{
base.Controls.Add(e.Control.Parent);
}
base.OnControlAdded(e);
}
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