views:

133

answers:

4

Hi All,

I've come accross a problem, that is probably seen pretty often, but has never really been discussed here.

In my Gui, I'm adding Controls in a for loop to a Flowpanellayout. The point is to display "reports" from a database. It has to be dynamic, because the number of reports can be different from day to day.


Pseudocode Adding Gui Elements:

for(int i = 0; i < reports.Count; i++)
{
    TextBox textboxPerson = new TextBox();
    textboxPerson.Name = "TextboxName" + i;
    textboxPerson.Text = reports[i].Name;
    textboxPerson.TextChanged += new EventHandler(this.textboxPerson_TxtChanged);

    Label labelToChange = new Label();
    labelToChange.Name = "label"+i;
    labelToChange.Text = "";

    flowlayoutPanel.Controls.Add(textboxPerson);
    flowlayoutPanel.Controls.Add(labelToChange);
}

Event Handler:

private void textboxPerson_TextChanged(object sender, EventArgs e)
{
   //So far, I'm only getting the number of the Textbox that changed.
}


Here is, where I need your advise. The Textboxs and Labels are matching (iE, Texbox1 is as you can see connected to Label1). But how do I adress one Control in particular?

  • If Texbox1's Text changes, how do I address Label1 to change its Text or something?
  • Is there a state of the art of adding dynamic Gui Elements to a Form and handling them?

Thank you for your answers

+3  A: 

You can use the Tag property of the controls, for instance. In your loop, you can assign the Label to the Tag property of the TextBox like this:

TextBox textboxPerson = new TextBox();
// do the stuff with the text box

Label labelToChange = new Label();
// do the stuff with the label
textboxPerson.Tag = labelToChange

Then you can get to the Label in the TextChanged event of the TextBox:

private void textboxPerson_TextChanged(object sender, EventArgs e)
{
   //So far, I'm only getting the number of the Textbox that changed.
   Label theLabel = (sender as TextBox).Tag;
   theLabel.Text = "whatever should go here";
}
Fredrik Mörk
I do it also all the time this way. If you've to save more than only a reference to an other control, you can create a private inner class and the problem is solved (at least for me) :)
Gregor
thank you, this seems like just the thing I was looking for considering the complexity of my control
Pascalo
+2  A: 

You could think of writing your own little UserControl, which groups the TextBox and the Label. This is especially useful if your generated control set becomes larger (e.g. you are adding a button or two).

Best Regards

Oliver Hanappi
+1. In that case, the Repeater control included in Visual Studio 2008 SP1 might be a better fit than FlowLayoutPanel.
OregonGhost
+2  A: 

In your particular case, you can use data binding to link the Label to the TextBox:

for (int i = 0; i < reports.Count; i++) {
  TextBox textboxPerson = new TextBox();
  textboxPerson.Name = "TextboxName" + i;
  textboxPerson.Text = reports[i].Name;
  //textboxPerson.TextChanged += new EventHandler(this.textboxPerson_TxtChanged);

  Label labelToChange = new Label();
  labelToChange.Name = "label" + i;
  labelToChange.Text = "";

  // this will update labelToChange.Text whenever textboxPerson.Text changes
  labelToChange.DataBindings.Add("Text", textboxPerson, "Text");

  flowlayoutPanel.Controls.Add(textboxPerson);
  flowlayoutPanel.Controls.Add(labelToChange);
}

If you use this, you don't even have to handle the TextChanged event

Julien Poulin
+1 nice idea, didn't know this is possible
Gregor
thanks, this makes very much sense for my example.
Pascalo
A: 

Do like this in your event handler:

string labelName = ((Control)sender).Name.Replace("TextboxName","label");
Label [] labels = FlowlayoutPanel.Controls.Find(labelName,false);
if (labels.Length > 0)
    labels[0].Text = "This is your attached label";
sindre j
It is normally advisable to utilize the .Tag property, but I have experienced the need to get spesific controls by name, so I just wanted to show you how I normally solve those cases.
sindre j