【问题标题】:How to reliably reference the containing form如何可靠地引用包含表单
【发布时间】:2014-02-08 11:07:08
【问题描述】:

在什么情况下,当最初加载 WinForms 自定义控件(继承自 TextBox)时,是否可以且适当地可靠地引用父窗体?

四处搜索后,我发现一个涵盖该领域的讨论是.NET WinForms Custom Control: how to get a reference to the containing form。具体来说,adrift 的帖子涉及到在将自定义控件添加到父窗体(并且 OnParentChanged 事件触发)之前,FindForm 将返回 null 的问题。

基于此,建议使用 OnParentChanged 事件。不幸的是,我发现如果自定义控件包含在另一个控件(例如面板)中,则此容器不一定会添加到表单的控件集合中,即使在自定义控件的 OnParentChanged 事件中,FindForm 也会返回 null。

因此,我想知道是否有更好的事件可以使用,它可以可靠地允许 FindForm 用于返回自定义控件的父窗体(即使它被放置在另一个容器控件中)。

【问题讨论】:

  • 与论坛网站不同,我们不使用“谢谢”、“感谢任何帮助”或Stack Overflow 上的签名。请参阅“Should 'Hi', 'thanks,' taglines, and salutations be removed from posts?.
  • 而且,顺便说一句,您的意思是“非常受欢迎”,而不是“非常受欢迎”。
  • 克里斯,感激地也意味着标记答案,或者至少评论建议的答案;-)
  • Luc,虽然我仍在解决这个问题(主要是在您对另一个问题的帮助下),但我会在第二天左右发表评论/标记为答案 - 非常感谢; -)
  • 约翰,感谢您对礼仪的见解 - 温柔一点,我是堆栈溢出的新手贡献者

标签: .net winforms custom-controls


【解决方案1】:

根据我对您的问题的理解,您可能可以在自定义控件上实现 ISupportInitialize 接口。

这将允许您的控件代码由您的 Form 的 InitializeComponent() 方法调用。

例如,这个从 Button 派生的简单用户控件:

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

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

当放置在表单上时,设计器代码将如下所示:

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();
}

如您所见,一旦 Form 初始化完成,就会在您的控件上调用 EndInit()。此时this.TopLevelControl 不会为空。

我不确定这是否是您要查找的内容,如果不是,请不要犹豫,为您的问题添加更多上下文。

干杯

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-27
    • 1970-01-01
    • 2011-09-06
    • 2022-12-11
    • 1970-01-01
    • 1970-01-01
    • 2020-09-15
    • 1970-01-01
    相关资源
    最近更新 更多