VS2017为何频繁丢失自定义派生控件?如何恢复?
你遇到的这个Designer不生成控件实例化语句的问题,我之前做WinForms自定义控件时也碰到过几次,大概率是以下几个原因之一,咱们一步步排查解决:
可能的原因&对应解决办法
1. 自定义控件缺少公共无参数构造函数
WinForms Designer要求所有可拖放的控件必须有一个public的无参数构造函数,如果你的派生类(比如DRT_Button_CancelSearch)没有显式定义,或者构造函数的访问修饰符是internal/private,Designer就无法自动生成实例化代码。
解决办法:
给每个具体的自定义控件类添加public无参数构造函数,并且确保调用基类的构造函数:
internal class DRT_Button_CancelSearch : DRT_Button_Abstract { // 必须添加这个public无参构造函数 public DRT_Button_CancelSearch() : base() { // 你的初始化逻辑 } }
另外,你的抽象基类DRT_Button_Abstract也需要有至少一个protected的构造函数(供派生类调用),比如:
internal abstract class DRT_Button_Abstract : Button { protected DRT_Button_Abstract() : base() { // 基类初始化逻辑 } }
2. 控件类的访问修饰符限制
虽然你用了internal修饰控件类,但如果主窗体项目和控件类所在的项目不是同一个程序集,internal会导致Designer无法访问该类(internal仅对同一程序集可见)。你说能拖到工具箱大概率是同程序集,但保险起见,建议把具体的控件类改成public试试,或者确认跨项目引用的可见性设置正确。
3. WinForms Designer缓存损坏
有时候Designer的临时缓存会出错,导致代码生成异常。可以尝试以下操作:
- 关闭Visual Studio,删除项目目录下的
.vs隐藏文件夹,重新打开项目。 - 右键主窗体文件,选择**"转换为本地资源"**(若有该选项),或手动清理Designer.cs中无效代码后重新添加控件。
- 执行生成 -> 清理解决方案,再生成 -> 重新生成解决方案。
4. 控件基类构造函数未正确调用
如果抽象基类DRT_Button_Abstract没有正确调用Button的基类构造函数,也可能导致Designer无法正常实例化派生类。务必确保基类构造函数调用了base(),参考上面代码中的写法。
验证步骤
修改完成后先重新生成整个解决方案,再尝试将控件拖到窗体上,打开Design视图检查Designer.cs文件,确认是否生成了new语句。如果仍有问题,可以创建一个空白WinForms项目,复制自定义控件代码进去测试,排查是否是当前项目的环境问题。
内容的提问来源于stack exchange,提问作者VA systems engineer

