Yustme
Yustme

Reputation: 6265

Cast TextBox control from linq query

I'm trying to get a TextBox control from a collection which only contains TextBoxes as follow:

IEnumerable<TextBox> tbx = this.grd.Children.OfType<TextBox>();

And then I'm trying to get the TextBox control that has the name "tbxLink" as follow:

TextBox txtBox = (TextBox)tbx.Select(x => x.Name == "tbxLink");

But it gives me this error message at runtime:

Unable to cast object of type 'WhereSelectEnumerableIterator`2[System.Windows.Controls.TextBox,System.Boolean]' to type 'System.Windows.Controls.TextBox'.

What am I missing here?

Edit:

Some more tries with some more error messages:

Using .Where:

Unable to cast object of type 'WhereEnumerableIterator`1[System.Windows.Controls.TextBox]' to type 'System.Windows.Controls.TextBox'.

Using .Single:

Sequence contains no matching element

Using .First :

Sequence contains no matching element

Using FirstOrDefault or SingleOrDefault makes the tbx variable null

Upvotes: 1

Views: 1133

Answers (1)

Phil
Phil

Reputation: 43011

You would normally use Where like this:

 IEnumerable<TextBox> textBoxes = tbx.Where(x=>x.Name == "tbxLink");

where textBoxes is IEnumerable<TextBox>.

But if you know there is only one text box with that name you need

tbx.SingleOrDefault(x => x.Name == "tbxLink");

which will return null (of more precisely default(TextBox)) if there is no text box of that name,

or alternatively

tbx.Single(x => x.Name == "tbxLink");

which throws an exception if no text box of that name exists.

If there are multiple text boxes with the same name you may want to use

tbx.FirstOrDefault(x => x.Name == "tbxLink");

or

tbx.First(x => x.Name == "tbxLink");

As an example running this code in LINQPad works as expected:

void Main()
{
     IEnumerable<TextBox> items = new List<TextBox>{
        new TextBox{ Name = "One" },
        new TextBox{ Name = "Two" },
        new TextBox{ Name = "Three" },
        new TextBox{ Name = "Four" },
    };

    items.Single (i => i.Name == "One").Dump();
}

class TextBox
{
    public string Name {get;set;}
}

I have duplicated this using WPF, e.g.

    private void Button_Click_1(object sender, System.Windows.RoutedEventArgs e)
    {
        IEnumerable<TextBox> textBoxes = grid.Children.OfType<TextBox>();

        var textBox = textBoxes.Single(tb => tb.Name == "one");

        Debug.WriteLine(textBox.Name);
    }

Upvotes: 2

Related Questions