Misiu
Misiu

Reputation: 4919

ControlDesigner not active when dragging control from Toolbox

I'm trying to add designer support for my custom WinForms control, but it looks designer is only active when I already have instance created, not during drag'n'drop from Toolbox.

To show what I mean I've created simple control with designer:

[Designer(typeof(MyButtonDesigner))]
public class MyButton:Button
{
    public MyButton()
    {
        base.Size= new Size(50,50);
    }
}
class MyButtonDesigner : ControlDesigner
{
    public override bool CanBeParentedTo(IDesigner parentDesigner)
    {
        return parentDesigner != null && parentDesigner.Component is Form;
    }
}

I'd like my control to by hosted only by form (user will be able to add control only to form, not to groupbox). When I drag control from Toolbox my validation logic is skipped, but when I try to move my control instance from form to groupbox I can see that drop is validated (as shown below)

enter image description here

I'm quite new to ControlDesigner so I'm not sure if this behavior is by design or can I change this so that my validation will work when dragging from Toolbox.

I'm using Visual Studio 2013, but I don't think this should be an issue.

Upvotes: 3

Views: 503

Answers (1)

Reza Aghaei
Reza Aghaei

Reputation: 125197

CanBeParentedTo method is not called when an item is dragged from the Toolbox onto the design surface.
You can create a custom ToolBoxItem for your control and then override CreateComponentsCore method to prevent creating control when the parent is not Form. The ToolBoxItem will be used when dragging control from ToolBox and the Designer will be used when dragging control from design-surface.

//Add reference to  System.Drawing.dll then using
using System.Drawing.Design;
using System.Windows.Forms.Design;
public class MyButtonToolBoxItem:ToolboxItem
{
    protected override IComponent[] CreateComponentsCore(IDesignerHost host,
        System.Collections.IDictionary defaultValues)
    {
        if(defaultValues.Contains("Parent"))
        {
            var parent = defaultValues["Parent"] as Control;
            if(parent!=null && parent is Form)
                return base.CreateComponentsCore(host, defaultValues);
        }

        var svc = (IUIService)host.GetService(typeof(IUIService));
        if (svc != null) svc.ShowError("Can not host MyButton in this control");

        return null;
    }
}

To register the toolbox item for your control:

[ToolboxItem(typeof(MyButtonToolBoxItem))]
[Designer(typeof(MyButtonDesigner))]
public class MyButton : Button

As result, when you drag your control from toolbox and drop it on any container other than form, it shows a message to the user and nothing happens and it will not added to that parent. If you like, you can remove the messagebox.

Upvotes: 3

Related Questions