自动生成的代码中未自定义自定义用户控件

Eug*_*yos 12 c# user-controls designer custom-controls visual-studio

这种情况以前发生了很多次,但我从来没有费心去弄清楚原因,现在我已经厌倦了:

例如,我从RichTextBox或Panel派生一个类,我重建我的项目以将类添加到VS设计器工具箱,然后将自定义用户控件拖放到Form.一切正常,我可以运行我的项目......

当我通过设计器编辑窗体或自定义用户控件的属性时出现问题.有时,设计器会从其代码隐藏中删除初始化行,从而导致设计器和可执行文件中出现异常,因为控件仍然未初始化.

换句话说,从Form1.Designer.cs中删除以下行:

this.customRichTextBox1=new CustomRichTextBox();
Run Code Online (Sandbox Code Playgroud)

没有其他行从代码隐藏中删除,因此自定义控件的属性仍然设置,尽管变量保持未初始化.

我的解决方案一直是在设计器代码隐藏中手动初始化我的用户控件,但设计人员最终会再次删除它.

我相信当我通过设计器构建自定义用户控件时,这不会发生(但我不完全确定).它只发生在我手动定义类似下面的内容时:

class CustomRichTextBox:RichTextBox{}
Run Code Online (Sandbox Code Playgroud)

这太烦人了.我究竟做错了什么?


正如@Cody所要求的,以下是重现问题的步骤.我正在使用VS2010,但我认为自2005年以来我遇到了这个问题.

步骤1.创建新的Windows窗体应用程序,任何框架

步骤2.在主Form类下面添加以下类:(这恰好是这次导致我出现此问题的控件.)

class CustomRichTextBox : RichTextBox
{
    Timer tt = new Timer();

    internal CustomRichTextBox()
    {
        tt.Tick += new EventHandler(tt_Tick);
        tt.Interval = 200;
    }


    protected override void OnTextChanged(EventArgs e)
    {
        tt.Stop();
        tt.Start();
    }

    void tt_Tick(object sender, EventArgs e)
    {
        System.Diagnostics.Trace.WriteLine("Hello world!");
    }
}
Run Code Online (Sandbox Code Playgroud)

步骤3.按F6重建.

步骤4.通过从工具箱中拖放,将CustomRichTextBox控件添加到窗体.

步骤5.如果您愿意,可以按F5测试应用程序,但它应该可以工作.关闭正在运行的应用

步骤6.按F6重建,此时,设计人员应该崩溃并显示以下消息:"变量'customRichTextBox1'未声明或从未分配过." (在一种情况下,整个VS完全崩溃,但错误通常包含在设计器中.)

步骤7.要解决问题,请进入代码隐藏并初始化变量,但下次重建时,初始化行将消失.

Eug*_*yos 14

感谢所有尝试回答我的问题并发表了帮助我诊断和解决问题的评论的人.

在控件的构造函数中使用"internal"关键字时会出现问题.将其更改为"公共"可以解决问题.这种行为的原因可能是Designer自己的类无法看到构造函数,因为它们不在我的类的命名空间内,除非它被标记为public.这一切都有道理,我将从现在开始使用public关键字.

该类不需要位于其自己的单个文件中,也不需要作为其他答案建议的文件中的第一个声明的类.

以下类很有效,因为构造函数的关键字已更改为public.

class CustomRichTextBox : RichTextBox
{
    Timer tt = new Timer();

    public CustomRichTextBox()
    {
        tt.Tick += new EventHandler(tt_Tick);
        tt.Interval = 200;
    }


    protected override void OnTextChanged(EventArgs e)
    {
        tt.Stop();
        tt.Start();
    }

    void tt_Tick(object sender, EventArgs e)
    {
        System.Diagnostics.Trace.WriteLine("Hello world!");
    }
}
Run Code Online (Sandbox Code Playgroud)