AngryHacker -
I went off thinking this was to be very easy, and found myself embarking on an interesting journey into WinForm design-time land. This is definitely not as easy as it was in VB6 :-) .
Anyhow, after a bit of research, I found a number of references to a method called EnableDesignMode(). However, this is not directly accessible from a WinForm component. This has to be called from a class that subclasses ParentControlDesigner, which is injected into the UserControl via a Designer attribute. In this project, I have called the subclass ButtonBarDesigner, and have overridden the Initialize() method, which allows me to tell the designer that the component ButtonBar has a child component fillPanel which can be accessed via the public property "FillPanel".
At this point, it seemed to be working. I managed to drop a control onto the ButtonBar and it was appearing in the fill panel. However, if you saved the form, and then reloaded it, it turned out that the control was instantiated, but not placed in the ButtonBar control. It seems that there was one sneaky last bit which the documentation for EnableDesignMode() conveniently leaves out. You need to have the DesignerSerializationVisibility attribute on the FillPanel property. Adding this attribute makes this work.
You need a reference to System.Design in your project for the design time stuff to work.
The following code is for the putative base class, ButtonBar:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.Threading;
namespace ForceUserControl
{
[Designer(typeof(ButtonBarDesigner))]
public partial class ButtonBar : UserControl
{
public ButtonBar()
{
InitializeComponent();
}
/// <summary>
/// Returns inner panel.
/// </summary>
/// <remarks>Should allow persistence.</remarks>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Panel FillPanel
{
get { return fillPanel; }
}
}
private class ButtonBarDesigner : ParentControlDesigner
{
public override void Initialize(IComponent component)
{
base.Initialize(component);
Panel fillPanel = ((ButtonBar)component).FillPanel;
// The name should be the same as the public property used to return the inner panel control.
base.EnableDesignMode(fillPanel, "FillPanel");
}
}
}