从工具箱拖动控件时 ControlDesigner 未激活

ControlDesigner not active when dragging control from Toolbox

我正在尝试为我的自定义 WinForms 控件添加设计器支持,但看起来设计器仅在我已经创建了实例时处于活动状态,而不是在从工具箱拖放期间。

为了说明我的意思,我使用设计器创建了简单的控件:

[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;
    }
}

我希望我的控件仅由表单托管(用户将只能将控件添加到表单,而不是组框)。当我从工具箱中拖动控件时,我的验证逻辑被跳过,但是当我尝试将我的控件实例从表单移动到组框时,我可以看到拖放已验证(如下所示)

我是 ControlDesigner 的新手,所以我不确定这种行为是否是设计使然,或者我是否可以更改它以便在从工具箱拖动时我的验证可以正常工作。

我使用的是 Visual Studio 2013,但我认为这应该不是问题。

CanBeParentedTo 将项目从工具箱拖到设计图面上时不会调用方法。
您可以创建自定义 ToolBoxItem for your control and then override CreateComponentsCore 方法以防止在父级不是 Form 时创建控件。从工具箱拖动控件时将使用 ToolBoxItem,从设计界面拖动控件时将使用 Designer

//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;
    }
}

为您的控件注册工具箱项:

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

因此,当您将控件从工具箱中拖放到窗体以外的任何容器上时,它会向用户显示一条消息,但没有任何反应,并且不会添加到该父级。如果你愿意,你可以删除消息框。