【问题标题】:Access owner members in a nested class访问嵌套类中的所有者成员
【发布时间】:2009-12-15 11:06:21
【问题描述】:

我的表单中有一个特殊标签,它应该在工具提示中显示一些文本。 标签在表单中被声明为私有类(嵌套控件),并且应该“看到”父表单的 ToolTip 控件。

这里是代码。当然,我在这里得到错误,因为构造函数是在所有者表单控件集合中添加私有控件之前调用的......

编辑: 有没有可能在构造函数中不传递form1或toolTip控件?

using System;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsApplication2
{
    public partial class Form1 : Form
    {
        public Form1() 
        {
            this.InitializeComponent();

            FormLabel myFormLabel = new FormLabel("uraaaaa!");

            this.Controls.Add(myFormLabel);

            myFormLabel.Location = new Point(20, 20);
        }

        private class FormLabel : Label
        {
            public FormLabel(string toolTip) : base()
            {
                this.Text = toolTip.ToUpperInvariant();

                (this.FindForm() as Form1).toolTip1.SetToolTip(this, toolTip);
            }
        }
    }
}

【问题讨论】:

  • 您为什么想要将正确的表单传递给构造函数?这是实现您想要的最简单的方法,并且不需要 FindForm/ParentForm “准备好”。
  • 是的,但这不是一个公共类,在你的情况下,我可以将参数传递给 Form1 的另一个实例......最后,我不能否认你的建议有效,但是恕我直言,这不是优雅的解决方案。
  • @serhio:哪方面不优雅?它为类提供了它需要的所有信息,而不是依赖于初始化的确切时间等。因此它不那么脆弱,更简单......有什么不喜欢的?

标签: .net winforms .net-2.0 nested accessor


【解决方案1】:

为什么不直接将表单传递给 FormLabel 的构造函数?

public Form1() 
{
    this.InitializeComponent();
    FormLabel myFormLabel = new FormLabel(this, "uraaaaa!");
    this.Controls.Add(myFormLabel);
    myFormLabel.Location = new Point(20, 20);
}

private class FormLabel : Label
{
    public FormLabel(Form1 form, string toolTip) : base()
    {
        this.Text = toolTip.ToUpperInvariant();
        form.toolTip1.SetToolTip(this, toolTip);
    }
}

我希望它可以工作...如果没有,请详细说明您看到的错误。我认为在现实生活中这样做是有充分理由的 - 现在我觉得有点费解。

【讨论】:

  • 我也可以在构造函数中传递工具提示,但问题不在于在构造函数中传递补充参数..
  • @serhio:由于您的类是嵌套的,因此您可以访问包含类中所有已声明的成员。
  • @leppie ???换句话说,你说我可以从 Form1 标签中“看到” Form1 成员?怎么样?
  • @serhio:是的。获取表单的引用并访问它。编译器不会抱怨。
  • @leppie:“获取表单的参考”。我不明白。你建议我在构造函数中传递引用?
【解决方案2】:

您可以使用 ToolTip 的任何实例来设置工具提示 - 您可能会发现创建 ToolTip 的新实例比在表单上重新使用实例更容易:

public FormLabel(string toolTip) : base()
{
    this.Text = toolTip.ToUpperInvariant();

    ToolTip myToolTip = new ToolTip();
    myToolTip.SetToolTip(this, toolTip);
}

或者,您可以将 ToolTip 的实例显式传递给控件,​​如下所示:

public Form1() 
{
    this.InitializeComponent();

    FormLabel myFormLabel = new FormLabel("uraaaaa!", this.toolTip1);
    this.Controls.Add(myFormLabel);
    myFormLabel.Location = new Point(20, 20);
}

private class FormLabel : Label
{
    public FormLabel(string text, ToolTip toolTip) : base()
    {
        this.Text = text.ToUpperInvariant();
        toolTip.SetToolTip(this, text);
    }
}

这有助于澄清一些事情吗?

【讨论】:

  • toolTip.SetToolTip(this, toolTip);在构造函数中将不起作用,因为 this 还不是(在构造时)父表单的控件
  • this 不需要是控件表单的父级即可设置工具提示。
【解决方案3】:

临时解决方案可以是:

using System;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsApplication2
{
    public partial class Form1 : Form
    {
        public Form1(){
            this.InitializeComponent();
            FormLabel myFormLabel = new FormLabel("uraaaaa!");
            this.Controls.Add(myFormLabel);
            myFormLabel.Location = new Point(20, 20);
        }

    private class FormLabel : Label
    {
        private string toolTipText;
        public FormLabel(string toolTip) : base() {                
            this.BorderStyle = BorderStyle.FixedSingle;
            this.toolTipText = toolTip.ToUpperInvariant();
        }

        protected override void OnParentChanged(EventArgs e) {
            Form1 f1 = (this.Parent as Form1);
            if (f1 != null)
                f1.toolTip1.SetToolTip(this, this.toolTipText);
        }
    }
}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-25
    • 2015-03-06
    • 1970-01-01
    相关资源
    最近更新 更多