You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Control Designer添加属性?自定义控件设计器动词与下拉菜单扩展疑问

自定义ControlDesigner添加属性关联动词及下拉菜单实现方案

嗨,我来帮你搞定这个自定义控件设计器的问题!我知道你已经会用DesignerVerbCollection添加基础设计器动词,但卡在了怎么绑定控件属性的动词,还有实现带下拉菜单的多级选项上——这俩需求我都帮你拆解清楚!

一、添加与控件属性关联的DesignerVerb

要实现像“编辑项...”“编辑列...”这种和控件属性绑定的动词,关键是在动词的回调逻辑里直接唤起对应属性的编辑器,和你在属性窗口里编辑该属性的体验完全一致。

给你举个实际的例子:假设你的自定义控件有一个ItemCollection类型的Items属性,要添加“Editar elementos...”(编辑项...)的动词,代码可以这么写:

public class MyCustomControlDesigner : ControlDesigner
{
    private DesignerVerbCollection _verbs;

    public override DesignerVerbCollection Verbs
    {
        get
        {
            if (_verbs == null)
            {
                _verbs = new DesignerVerbCollection();
                // 添加关联Items属性的编辑动词
                _verbs.Add(new DesignerVerb("Editar elementos...", (sender, e) => 
                {
                    var targetControl = (MyCustomControl)Component;
                    // 获取属性描述器,唤起内置的集合编辑器
                    var propDescriptor = TypeDescriptor.GetProperties(targetControl)["Items"];
                    var collectionEditor = propDescriptor.GetEditor(typeof(UITypeEditor)) as UITypeEditor;
                    
                    if (collectionEditor != null)
                    {
                        var editorService = GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
                        collectionEditor.EditValue(editorService, targetControl, propDescriptor.GetValue(targetControl));
                    }
                }));
                // 同理添加关联Columns属性的"Editar columnas..."动词
                _verbs.Add(new DesignerVerb("Editar columnas...", (sender, e) => 
                {
                    // 复制上面的逻辑,把"Items"替换成你的Columns属性名即可
                }));
            }
            return _verbs;
        }
    }
}

点击这个动词时,就会弹出和属性窗口里编辑Items属性一样的集合编辑器对话框,完全符合你的需求。

二、实现带下拉菜单的多级设计器选项

默认的DesignerVerb只能做单级菜单,要实现像“Vista”(视图)这种带下拉子项的效果,得用DesignerActionList——这是VS设计器用来做智能标签多级菜单的标准方式。

步骤1:自定义DesignerActionList类

先写一个包含下拉菜单逻辑的ActionList:

public class MyCustomControlActionList : DesignerActionList
{
    private readonly MyCustomControl _control;
    private readonly DesignerActionUIService _uiService;

    public MyCustomControlActionList(MyCustomControl control) : base(control)
    {
        _control = control;
        _uiService = (DesignerActionUIService)GetService(typeof(DesignerActionUIService));
    }

    public override DesignerActionItemCollection GetSortedActionItems()
    {
        var actionItems = new DesignerActionItemCollection();
        
        // 添加分组标题(对应你的"Vista")
        actionItems.Add(new DesignerActionHeaderItem("Vista"));
        
        // 添加下拉子项(对应你的"ImageList pequeña"等选项)
        actionItems.Add(new DesignerActionMethodItem(
            this, 
            nameof(SetSmallImageList), 
            "ImageList pequeña", 
            "Vista", 
            "切换为小型ImageList"));
        
        actionItems.Add(new DesignerActionMethodItem(
            this, 
            nameof(SetLargeImageList), 
            "ImageList grande", 
            "Vista", 
            "切换为大型ImageList"));

        return actionItems;
    }

    // 子选项对应的执行逻辑
    public void SetSmallImageList()
    {
        // 这里写切换到小型ImageList的逻辑,比如给控件的ImageList属性赋值
        _control.ImageList = _control.SmallImageList;
        _uiService.Refresh(_control);
    }

    public void SetLargeImageList()
    {
        _control.ImageList = _control.LargeImageList;
        _uiService.Refresh(_control);
    }
}

步骤2:在ControlDesigner里关联ActionList

回到你的MyCustomControlDesigner,添加ActionList的重写逻辑:

public class MyCustomControlDesigner : ControlDesigner
{
    private DesignerActionListCollection _actionLists;

    // 保留之前的Verbs代码(处理单级编辑动词)
    private DesignerVerbCollection _verbs;
    public override DesignerVerbCollection Verbs
    {
        get
        {
            // 之前的代码不变
        }
    }

    // 添加ActionList的重写
    public override DesignerActionListCollection ActionLists
    {
        get
        {
            if (_actionLists == null)
            {
                _actionLists = new DesignerActionListCollection();
                _actionLists.Add(new MyCustomControlActionList((MyCustomControl)Component));
            }
            return _actionLists;
        }
    }
}

这样在设计器里,你的控件右上角会出现一个小箭头(智能标签按钮),点击后就能看到“Vista”分组下的下拉子菜单,和你示意图里的效果完全一致。

三、适配西班牙语Visual Studio的小提示

因为你的VS是西班牙语版本,系统自带的设计器文本(比如编辑器对话框的标题)会自动适配,但你自定义的动词和菜单文本直接写西班牙语就行(比如"Editar elementos..."),VS会直接显示你定义的内容,不用额外做本地化处理。

内容的提问来源于stack exchange,提问作者user9264959

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:38:55