Question

In which event, when initially loading a WinForms custom control (inherited from a TextBox), is it possible and appropriate to reliably reference the parent form?

Having searched around, one discussion I've found that covers this area is .NET WinForms Custom Control: how to get a reference to the containing form. Specifically, the posting by adrift touches upon the issue that until the custom control is added to the parent form (and the OnParentChanged event fires) the FindForm will return null.

Based on this, the suggestion is to use the OnParentChanged event. Unfortunately, I've found that if the custom control is contained within another control (e.g. a Panel) then this container won't necessarily be added to the form's control collection and the FindForm will return null even in the custom control's OnParentChanged event.

As a result, I wonder if there is a better event to use which will reliably allow the FindForm to be used to return the custom control's parent form (even when it's placed within another container control).

Was it helpful?

Solution

Based on my understanding of your problem, you could probably implement the ISupportInitialize interface on your custom control.

This would allow your control code to be called by the InitializeComponent() method of your Form.

For example, this simple user control deriving from Button:

class MyButton : Button, ISupportInitialize
{
    public void BeginInit()
    {
        var parent = this.TopLevelControl;
    }

    public void EndInit()
    {
        var parent = this.TopLevelControl;
    }
}

When placed on a Form, the designer code will look like this:

private void InitializeComponent()
{
    this.myButton1 = new Quartz1.MyButton();
    ((System.ComponentModel.ISupportInitialize)(this.myButton1)).BeginInit();
    this.SuspendLayout();
    // 
    // myButton1
    // 
    this.myButton1.Location = new System.Drawing.Point(371, 338);
    this.myButton1.Name = "myButton1";
    this.myButton1.Size = new System.Drawing.Size(75, 23);
    this.myButton1.TabIndex = 4;
    this.myButton1.Text = "myButton1";
    this.myButton1.UseVisualStyleBackColor = true;
    // 
    // Form1
    // 
    this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    this.ClientSize = new System.Drawing.Size(1012, 440);
    this.Controls.Add(this.myButton1);
    this.Name = "Form1";
    this.Text = "Form1";
    ((System.ComponentModel.ISupportInitialize)(this.myButton1)).EndInit();
    this.ResumeLayout(false);
    this.PerformLayout();
}

As you can see, once the Form initialization is done, EndInit() is called on your control. At this point this.TopLevelControl will not be null.

I'm not sure whether this is what you're looking for, if not please don't hesitate to add more context to your question.

Cheers

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top