C#设计时自动添加依赖组件并填充属性列表的实现方案
实现TC_Label的设计时功能方案
一、拖拽TC_Label时自动添加TC_AdsConnection组件
要实现这个设计时逻辑,需为TC_Label自定义组件设计器,利用.NET设计器扩展机制,在组件被添加到窗体时自动检查并创建依赖的TC_AdsConnection实例。
实现步骤与代码:
- 给
TC_Label标记自定义设计器特性; - 编写继承自
ControlDesigner的设计器类,在初始化时检查容器内的TC_AdsConnection实例,不存在则创建并关联。
using System.ComponentModel; using System.ComponentModel.Design; using System.Windows.Forms.Design; // 为TC_Label指定自定义设计器 [Designer(typeof(TC_LabelDesigner))] public class TC_Label : Label { public TC_AdsConnection TC_ADSClient { get; set; } // 原有业务逻辑... } // 自定义设计器类 public class TC_LabelDesigner : ControlDesigner { public override void Initialize(IComponent component) { base.Initialize(component); // 仅在设计模式下执行 if (component.Site == null || !component.Site.DesignMode) return; // 获取当前窗体容器的设计器宿主 var designerHost = (IDesignerHost)component.Site.GetService(typeof(IDesignerHost)); if (designerHost == null) return; // 检查容器内是否已有TC_AdsConnection实例 bool hasAdsConn = false; foreach (IComponent comp in designerHost.Container.Components) { if (comp is TC_AdsConnection) { hasAdsConn = true; break; } } // 无实例则创建并关联到当前TC_Label if (!hasAdsConn) { var newAdsConn = (TC_AdsConnection)designerHost.CreateComponent(typeof(TC_AdsConnection)); newAdsConn.Name = "tcAdsConnection1"; ((TC_Label)component).TC_ADSClient = newAdsConn; } } }
二、让TC_ADSClient属性下拉显示窗体中的TC_AdsConnection实例
通过自定义类型转换器,过滤当前容器内的TC_AdsConnection实例,实现属性窗口的下拉选择功能。
实现步骤与代码:
- 编写继承自
ReferenceConverter的类型转换器,筛选目标实例; - 给
TC_ADSClient属性标记类型转换器特性。
using System.ComponentModel; using System.Collections.Generic; // 自定义类型转换器 public class TC_AdsConnectionConverter : ReferenceConverter { public TC_AdsConnectionConverter(Type type) : base(type) { } public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) { if (context == null || context.Container == null) return base.GetStandardValues(context); // 收集容器内所有TC_AdsConnection实例 var connList = new List<TC_AdsConnection>(); foreach (IComponent comp in context.Container.Components) { if (comp is TC_AdsConnection adsConn && adsConn.Site.DesignMode) { connList.Add(adsConn); } } return new StandardValuesCollection(connList); } public override bool GetStandardValuesSupported(ITypeDescriptorContext context) { return true; // 启用下拉列表 } public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) { return true; // 仅允许选择列表内的值 } } // 给TC_ADSClient属性应用转换器 [Designer(typeof(TC_LabelDesigner))] public class TC_Label : Label { [TypeConverter(typeof(TC_AdsConnectionConverter))] public TC_AdsConnection TC_ADSClient { get; set; } // 原有业务逻辑... }
注意事项:
- 项目需引用
System.Design程序集(.NET Framework)或System.Windows.Forms.DesignNuGet包(.NET Core/.NET 5+); - 所有设计器逻辑仅在Visual Studio设计模式下触发,不会影响程序运行时行为;
- 自动创建的
TC_AdsConnection可在设计器中手动重命名、配置属性,后续添加的TC_Label会自动识别已存在的实例。
内容的提问来源于stack exchange,提问作者FGalan
相关产品推荐
相关产品推荐

