3

I want to locate a TextBox named "textBoxQH_N" where "_N" is a number from 1..96.

So, I've got this code:

String sTextBoxToFind = String.Format("textBoxQH{0}", QuarterHour);
TextBox tb = (TextBox)this.Controls.Find(sTextBoxToFind, true);

...but it gave me, "Cannot convert type 'System.Windows.Forms.Control[]' to 'System.Windows.Forms.TextBox'"

So I changed the second line to grab just the first returned val:

TextBox tb = (TextBox)this.Controls.Find(sTextBoxToFind, true)[0];

Which seems to work, but shouldn't a Control's Name property be unique to its owner? IOW, Find() should only return 0..1 controls, right?

B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862
  • possible duplicate of [Find a control in C# winforms by name](http://stackoverflow.com/questions/4483912/find-a-control-in-c-sharp-winforms-by-name) – Sergey Kalinichenko Apr 23 '12 at 17:25

4 Answers4

7

Find, with the second property set to true, is recursive. 'Name' is unique to that parent, but you're searching through lots of different parents. 'Name' isn't globally unique.

As suggested by Justin in another answer, First or FirstOrDefault is probably better than using [0] on the array. It does a better job of conveying your intentions to future readers.

Servy
  • 202,030
  • 26
  • 332
  • 449
  • 2
    This seems to be the most logical answer; although the documentation for the "Name" property never actually requires it to be unique (there are other ways of uniquely identifying a control), I believe uniqueness at the parent level is enforced by the Visual Studio IDE. – Robert Harvey Apr 23 '12 at 17:29
3

The Find method will find any matches, so even though it is only one match in your case, it could be numerous in other cases. You could probably use LINQ First here if you wanted something more semantically meaningful?

The MSDN on this is pretty clear on this method

Justin Pihony
  • 66,056
  • 18
  • 147
  • 180
1

It returns an array of Controls. try it like:

Control[] tb = this.Controls.Find("textBox1", true); //change the name of the control

or:

TextBox[] tbs = (TextBox[])this.Controls.Find("tb1", true);

As you can see, you must CAST to the correct type of object (in your case to array of TextBoxes). Hope it helps, bye

Mitja Bonca
  • 4,268
  • 5
  • 24
  • 30
1

Form API design point of view 0 and 1 choices are better to be returned as IEnumerable/collection/array to avoid need for null checks.

As pointed by other answers, Name of control does not have to be globally unique and Find actually may return more than 1 item.

Link to MSDN - Controls.Find

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179