Chris
Chris

Reputation: 1

InvalidCastException when getting Text from a Label referenced by dynamicaly built String, Fix?

NET Version: 3.5 Ok, I recieve an error (System.InvalidCastException was unhandled. Message="Unable to cast object of type 'System.Windows.Forms.Control[]' to type 'System.Windows.Forms.Label'.") when trying to get Text from a Label referenced by a dynamicly built string.

Here's my situation; I have an array of 250 labels named l1 - l250. What I want to do is loop through them using this while statement:

int c = 1; 
while (c < 251) 
{ 
string k = "l" + c.ToString(); //dynamic name of Control(Label) 
object ka = Controls.Find(k, true);  
string ct = ((Label)ka).Text;  //<<Error Occurs Here 
build = build + ct; 
c++; 
}

and get the text value of each to build a string named build.

I don't get any build errors, just this while debuging.

While debuging I can go down to view my local variables. When looking through these, I can view the contents of object ka; it does contain the correct Text value of the correct Label I want to "access". I just don't understand how to get there. The text value is listed under "[0]" which is the only subcatagory for "ka".

Upvotes: 0

Views: 218

Answers (2)

Anthony Pegram
Anthony Pegram

Reputation: 126932

Look at the return type of the Controls.Find() method. It returns a Control[] (an array), which explains your error message.

Unable to cast object of type 'System.Windows.Forms.Control[]' to type 'System.Windows.Forms.Label'

You would need to iterate over the array and cast the individual items in order to use it in the manner you intend.

A snippet of code that may assist you in selecting just the labels you want is something like this

var labelNames = Enumerable.Range(1, 250).Select(num => "l" + num.ToString());

var myLabels = from labelName in labelNames
                join label in this.Controls.OfType<Label>()
                on labelName equals label.Name
                select label;

StringBuilder builder = new StringBuilder();

foreach (Label label in myLabels)
{
    builder.Append(label.Text);
}

string output = builder.ToString();

The first statement creates an enumerable of all the valid names you wish to find, since there could be other labels in the control collection. The second statement uses Linq to join the label names to the labels on your form, and then selects the labels. Finally, you can iterate over the resultant label enumerable and add to a StringBuilder instance. After the loop, you can receive the output via the builder's ToString() method.

Full working sample:

private void button1_Click(object sender, EventArgs e)
{
    var labelNames = Enumerable.Range(1, 250).Select(num => "l" + num.ToString());

    var myLabels = from labelName in labelNames
                    join label in this.Controls.OfType<Label>()
                    on labelName equals label.Name
                    select label;

    StringBuilder builder = new StringBuilder();

    foreach (Label label in myLabels)
    {
        builder.Append(label.Text);
    }

    string output = builder.ToString();
    MessageBox.Show(output);
}

private void Form1_Load(object sender, EventArgs e)
{
    for (int i = 1; i <= 250; i++)
    {
        Label label = new Label();
        label.Name = "l" + i.ToString();
        label.Text = "_" + i.ToString();
        this.Controls.Add(label);
    }
}

Upvotes: 1

Andy Ross
Andy Ross

Reputation: 1

the value returned from find is an array of objects, so you would want to do: string ct = ((Label)ka[0]).Text;

here's the doc: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.controlcollection.find.aspx

Upvotes: 0

Related Questions