views:

108

answers:

3

Hello.

I have a special label in my form, that should show in a tooltip some text. The label is declared as private class in the form (nested control), and should "see" the ToolTip control of the parent form.

Here is the code. Surely, I obtains errors here, because the constructor is called before the private control addition in the owner form control collection...

Edit: Is there a possibility do not pass the form1 or the toolTip control in constructor?

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);
            }
        }
    }
}
+1  A: 

Why not just pass the form into the constructor of 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);
    }
}

I would expect that to work... if it doesn't, please give details of what errors you're seeing. I'm assuming there's a good reason to do this in real life - it feels a bit convoluted to me at the moment.

Jon Skeet
I can pass the toolTip in constructor too but the question is not in passing supplementary parameters in constructor..
serhio
@serhio: as your class is nested, you have access to all the declared members in the containing class.
leppie
@leppie ??? in other words, you say that from FormLabel I can "see" the Form1 members? How?
serhio
@serhio: yes. Get a reference of the form and access it. The compiler wont complain.
leppie
@leppie: "Get a reference of the form". I don't understand. You propose me to pass the reference in constructor?
serhio
@serhio: where ever you want. Point is, if you have Form1 f, you can access the tooltip as f.toolTip1, like you did in your question.
leppie
@serhio: FormLabel has access to the members of an instance of Form1, because it's within the program text of Form1.
Jon Skeet
so, I need to **pass** somehow a reference to the form1 to my Label. Is no other way to obtain it?..
serhio
I believe that you can use this.Parent inside your FormLabel class to get a reference to the containing Form (Form inherits from Control)
Kragen
@Kragen: Yes, but only after it's been added to the parent control... @serhio: Why are you trying so desperately to avoid the most obvious solution?
Jon Skeet
@jon:I have problems with... because in the constructor I can't set the tooltip. is not added to the controls form yet.
serhio
@serhio: That's going to be a problem however you pass it. Either make the FormLabel add itself to the form, or set the tooltip afterwards.
Jon Skeet
+1  A: 

You can use any instance of ToolTip to set a tooltip - You may find it easier to create a new instance of ToolTip, rather than re-using the one on the Form:

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

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

Alternatively you could explicitly pass an instance of ToolTip to the control, like this:

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

Does this help clarify things a little?

Kragen
toolTip.SetToolTip(this, toolTip); in constructor will not work, because **this** is not yet(at construction time) a control of parent form
serhio
It works fine - I just tried it
Kragen
**this** doesn't need to be a parent of the control form in order to set a tooltip.
Kragen
A: 

A temporary solution can be like:

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