Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom User Control Not Initialized in Auto-Generated Code

This has happened many times before, but I never bothered to figure out why, and now I am tired of it:

For instance, I derive a class from RichTextBox or Panel, I rebuild my project to have the class added to the VS designer toolbox, and then I drag & drop the custom user control to a Form. Everything works fine, and I can run my project...

The problem comes when I edit properties of the Form or the custom user control through the designer. Sometimes, the designer removes the initialization line from its code-behind, causing an exception in the designer and the executable because the control remains uninitialized.

In other words, the following line is removed from say, Form1.Designer.cs:

this.customRichTextBox1=new CustomRichTextBox();

No other line is removed from the code-behind, so the attributes of the custom control are still set, although the variable stays uninitialized.

My solution has always been to manually initialize my user control in the designer code-behind, but the designer eventually removes it again.

I believe that this does not happen when I build a Custom UserControl through the designer (but I am not completely sure of this). It only happens when I define something like the following manually:

class CustomRichTextBox:RichTextBox{}

This is so annoying. What am I doing wrong?


As @Cody requested, here are the steps to reproduce the problem. I am using VS2010, but I've had this problem since 2005, I think.

Step 1. Create new Windows Forms Application, any Framework

Step 2. Add the following class below your main Form class: (It just happens that this is the control that is causing me this problem this time.)

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!");
    }
}

Step 3. Press F6 to rebuild.

Step 4. Add the CustomRichTextBox control to your Form by dragging and dropping from the Toolbox.

Step 5. If you wish, you may press F5 to test the application, but it should work. Close the running application.

Step 6. Press F6 to rebuild, and at this point, the designer should crash with the following message: "The variable 'customRichTextBox1' is either undeclared or was never assigned." (In one case, the whole VS completely crashed, but the error is usually contained within the designer.)

Step 7. To correct the issue, go into the code-behind and initialize the variable, but next time you rebuild, the initialization line will be gone.

like image 377
Eugenio De Hoyos Avatar asked Apr 16 '11 05:04

Eugenio De Hoyos


1 Answers

Thanks to everyone who tried answering my question and who posted comments that helped me diagnose and solve the problem.

The problem occurs when using an "internal" keyword with the control's constructor. Changing it to "public" fixes the problem. The reason for this behavior might be that the Designer's own classes cannot see the constructor because they are not within the namespace of my class unless it is marked public. This all makes sense, and I will use the public keyword from now on.

The class does not need to be in its own individual file or be the first declared class in the file as other answers suggested.

The following class works well because the constructor's keyword was changed to 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!");
    }
}
like image 127
Eugenio De Hoyos Avatar answered Oct 14 '22 06:10

Eugenio De Hoyos