自定义ParentControlDesigner:设计时点击添加控件拦截失败问题
解决UserControlEx设计器中拦截“选中工具箱控件后点击添加”的问题
要拦截第二种添加控件的方式(选中工具箱控件后点击用户控件),你需要重写ParentControlDesigner的GetToolSupported和CreateTool方法,同时修正CanAddComponent的逻辑,以下是具体实现:
自定义设计器实现
public class UserControlExDesigner : ParentControlDesigner { private UserControlEx HostControl => (UserControlEx)Control; // 校验工具箱工具是否允许被添加到当前设计器宿主 public override bool GetToolSupported(ToolboxItem tool) { // 根据你的ContentType规则判断是否允许添加 if (HostControl.ContentType == ContentType.Restricted) { // 禁止所有控件添加,也可以针对特定工具类型做判断 return false; } return base.GetToolSupported(tool); } // 重写CreateTool作为二次拦截,避免绕过GetToolSupported的情况 public override void CreateTool(ToolboxItem tool, Point location) { if (!GetToolSupported(tool)) { // 可选:通过DesignerMessageBox给用户提示 // DesignerMessageBox.Show("当前控件类型不允许添加组件", "提示"); return; } base.CreateTool(tool, location); } // 处理直接通过组件面板或代码添加组件的情况 public override bool CanAddComponent(IComponent component) { if (HostControl.ContentType == ContentType.Restricted && component is Control) { return false; } return base.CanAddComponent(component); } }
关联设计器到UserControlEx
[Designer(typeof(UserControlExDesigner))] public class UserControlEx : UserControl { public ContentType ContentType { get; set; } } public enum ContentType { Normal, Restricted }
为什么之前的方法无效?
CanAddComponent:若之前的实现未结合ContentType和组件类型做精准判断,或该方法未覆盖到工具箱点击添加的路径(此路径优先走GetToolSupported校验),会导致拦截失效。- 鼠标事件/WndProc拦截:Visual Studio设计器框架封装了工具创建的上层逻辑,底层事件拦截无法触达框架的校验流程。
ControlAdded事件抛异常:属于事后补救,不符合设计器扩展的事前校验规范,且会带来不必要的异常抛出。
通过上述实现,两种添加控件的方式都会被事前拦截,完全符合设计器扩展的标准流程,无需依赖事后事件处理。
内容的提问来源于stack exchange,提问作者IV.
相关产品推荐
相关产品推荐

