Home > database >  My user control should only be added to a certain type of control
My user control should only be added to a certain type of control

Time:01-01

How can I make it so that my user control can only be added in a certain type of control (here in my case, specifically SplitContainer)?

CodePudding user response:

You need to take care of a few things:

  1. Control's toolbox item behavior
  2. Control's designer behavior
  3. Control's run-time runtime behavior (optional)

When you drop the control from toolbox on a design surface, you should prevent it from being dropped on an undesired control; it's responsibility of CreateComponents method of the ToolBoxItem class assigned to the control.

After the control added to the design surface (for example in the desired parent), then you need to prevent dragging it over undesired controls; it's responsibility of CanBeParentedTo method of the ControlDesigner class assigned to the control.

Finally, you may want to even prevent adding it to undesired controls programmatically at run-time; which in this case, it's responsibility of OnParentChanged method of the control.

Example - Limit a control to be hosted only in a SplitterContainer

using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;
[ToolboxItem(typeof(MyControlToolBoxItem))]
[Designer(typeof(MyControlDesigner))]
public class MyControl : Control
{
    protected override void OnParentChanged(EventArgs e)
    {
        if (Parent != null && !(Parent is SplitterPanel))
            throw new Exception("You can add this control only to a SplitterContainer.");
        base.OnParentChanged(e);
    }
}
public class MyControlDesigner : ControlDesigner
{
    public override bool CanBeParentedTo(IDesigner parentDesigner)
    {
        if (parentDesigner.Component is SplitterPanel)
            return true;
        else
            return false;
    }
}
public class MyControlToolBoxItem : ToolboxItem
{
    protected override IComponent[] CreateComponentsCore(IDesignerHost host,
        System.Collections.IDictionary defaultValues)
    {
        if (defaultValues.Contains("Parent"))
        {
            var parent = defaultValues["Parent"];
            if (parent != null && parent is SplitterPanel)
                return base.CreateComponentsCore(host, defaultValues);
        }
        var svc = (IUIService)host.GetService(typeof(IUIService));
        if (svc != null) 
            svc.ShowError("You can drop this control only over a SplitterContainer.");
        return null;
    }
}
  • Related