C# 将子项添加到UserControl

C# 将子项添加到UserControl,c#,winforms,C#,Winforms,我创建了一个用户控件,现在我希望能够对其进行设置,以便可以将子控件添加到它的每个实例中 这就是它的布局: 红色框是我希望能够添加子项的面板。我的想法是在winforms应用程序中使用此控件,然后将新控件拖放到红色父容器中 我该怎么做 我只是想知道是否有可能将工具箱中的项拖动到其中一个红色区域,使其成为用户控件的子项 是的,有可能: [Designer(typeof(MyUserControlDesigner))] public partial class MyUserControl : Use

我创建了一个用户控件,现在我希望能够对其进行设置,以便可以将子控件添加到它的每个实例中

这就是它的布局:

红色框是我希望能够添加子项的面板。我的想法是在winforms应用程序中使用此控件,然后将新控件拖放到红色父容器中

我该怎么做

我只是想知道是否有可能将工具箱中的项拖动到其中一个红色区域,使其成为用户控件的子项

是的,有可能:

[Designer(typeof(MyUserControlDesigner))]
public partial class MyUserControl : UserControl
{
}
您必须实现一个设计器类。这就是如何在设计时将控件添加到内部
Content
面板(假设该面板作为公共
PanelContent
属性公开):

内部密封类MyUserControlDesigner:ParentControlDesigner
{
IDesignerHost designerHost;
公共覆盖无效初始化(IComponent组件)
{
初始化(组件);
base.AutoResizeHandles=true;
EnableDesignMode(((MyUserControl)组件).PanelContent,“ContentPanel”);
designerHost=(IDesignerHost)component.Site.GetService(typeof(IDesignerHost));
}
公共覆盖bool CANPERENT(控制)
{
返回false;
}
公共覆盖System.Collections.ICollection关联组件
{
得到
{
列表=新列表();
foreach(在((MyUserControl)Control.PanelContent.Controls中的控件)
{
列表。添加(控制);
}
退货清单;
}
}
受保护的覆盖控件GetParentForComponent(IComponent组件)
{
返回((MyUserControl)控件);
}
公共覆盖int NumberOfInternalControlDesigners()
{
返回1;
}
公共覆盖控制设计器InternalControlDesigner(int internalControlIndex)
{
控制面板=((MyUserControl)Control).PanelContent;
开关(内部控制索引)
{
案例0:
将此.designerHost.GetDesigner(面板)作为ControlDesigner返回;
违约:
返回null;
}
}
受保护的覆盖IComponent[]CreateToolCore(ToolboxItem工具、int x、int y、int width、int height、bool hasLocation、bool hasSize)
{
ParentControlDesigner panelDesigner=this.designerHost.GetDesigner(((MyUserControl)Control).PanelContent)作为ParentControlDesigner;
调用CreateTool(panelDesigner,工具);
返回null;
}
}

如果要公开多台主机,可以修改
numberofInternalControlDesigner
InternalControlDesigner
方法。然而,它从来没有真正为我工作。您可以根据要添加的组件决定应该使用哪个父级(请参见
GetParentForComponent
),但这意味着,例如按钮总是添加到按钮面板。我建议仅将内容面板作为父级提供,并使用一些公共属性来操作按钮面板。

在用户控件中对功能进行编码。例如,
buttonPanel.Items.Add(someButton)
或者您希望我们让拖放HahaControl具有子控件集合
,此链接将很有帮助:要进行拖放,可以很容易地看到一些教程。da代码在哪里“我可以将子控件添加到每个实例”是什么意思?是否要将其用作设计器中的容器控件?还是在运行时以编程方式?谢谢。我只是在内容方面做了一些工作,但并没有像你说的那样让这两个方面都发挥作用。我决定用代码来代替。我认为这需要更长的时间,但我现在没有时间阅读有关设计时支持的全部文档。不过,我会记住这一点,谢谢你。
internal sealed class MyUserControlDesigner : ParentControlDesigner
{
    IDesignerHost designerHost;

    public override void Initialize(IComponent component)
    {
        base.Initialize(component);
        base.AutoResizeHandles = true;
        base.EnableDesignMode(((MyUserControl)component).PanelContent, "ContentPanel");
        designerHost = (IDesignerHost)component.Site.GetService(typeof(IDesignerHost));
    }

    public override bool CanParent(Control control)
    {
        return false;
    }

    public override System.Collections.ICollection AssociatedComponents
    {
        get
        {
            List<Control> list = new List<Control>();
            foreach (Control control in ((MyUserControl)Control).PanelContent.Controls)
            {
                list.Add(control);
            }
            return list;
        }
    }

    protected override Control GetParentForComponent(IComponent component)
    {
        return ((MyUserControl)Control).PanelContent;
    }

    public override int NumberOfInternalControlDesigners()
    {
        return 1;
    }

    public override ControlDesigner InternalControlDesigner(int internalControlIndex)
    {
        Control panel = ((MyUserControl)Control).PanelContent;
        switch (internalControlIndex)
        {
            case 0:
                return this.designerHost.GetDesigner(panel) as ControlDesigner;
            default:
                return null;
        }
    }

    protected override IComponent[] CreateToolCore(ToolboxItem tool, int x, int y, int width, int height, bool hasLocation, bool hasSize)
    {
        ParentControlDesigner panelDesigner = this.designerHost.GetDesigner(((MyUserControl)Control).PanelContent) as ParentControlDesigner;
        InvokeCreateTool(panelDesigner, tool);
        return null;
    }
}