views:

434

answers:

2

I am trying to make my own user control and have almost finished it, just trying to add some polish. I would like the option in the designer to "Dock in parent container". Does anyone know how to do this I can't find an example. I think it has something to do with a Docking Attribute.

A: 

If your control inherits from UserControl (or most other controls available), you just need to set the Dock property to DockStyle.Fill.

Thorsten Dittmar
+3  A: 

I order to achieve this you will need to implement a couple of classes; first you will need a custom ControlDesigner and then you will need a custom DesignerActionList. Both are fairly simple.

The ControlDesigner:

public class MyUserControlDesigner : ControlDesigner
{

    private DesignerActionListCollection _actionLists;
    public override System.ComponentModel.Design.DesignerActionListCollection ActionLists
    {
        get
        {
            if (_actionLists == null)
            {
                _actionLists = new DesignerActionListCollection();
                _actionLists.Add(new MyUserControlActionList(this));
            }
            return _actionLists;
        }
    }
}

The DesignerActionList:

public class MyUserControlActionList : DesignerActionList
{
    public MyUserControlActionList(MyUserControlDesigner designer) : base(designer.Component) { }

    public override DesignerActionItemCollection GetSortedActionItems()
    {
        DesignerActionItemCollection items = new DesignerActionItemCollection();
        items.Add(new DesignerActionPropertyItem("DockInParent", "Dock in parent"));
        return items;
    }

    public bool DockInParent
    {
        get
        {
            return ((MyUserControl)base.Component).Dock == DockStyle.Fill;
        }
        set
        {
            TypeDescriptor.GetProperties(base.Component)["Dock"].SetValue(base.Component, value ? DockStyle.Fill : DockStyle.None);
        }
    }    
}

Finally, you will need to attach the designer to your control:

[Designer("NamespaceName.MyUserControlDesigner, AssemblyContainingTheDesigner")]
public partial class MyUserControl : UserControl
{
    // all the code for your control

Brief explanation

The control has a Designer attribute associated with it, which points out our custom designer. The only customization in that designer is the DesignerActionList that is exposed. It creates an instance of our custom action list and adds it to the action list collection that is exposed.

The custom action list contains a bool property (DockInParent), and creates an action item for that property. The property itself will return true if the Dock property of the component being edited is DockStyle.Fill, otherwise false, and if DockInParent is set to true, the Dock property of the component is set to DockStyle.Fill, otherwise DockStyle.None.

This will display the little "action arrow" close to the upper right corner of the control in the designer, and clicking the arrow will pop up the task menu.

Fredrik Mörk