Accessing asp.net tablerow child control by type

I'm iterating through a collection of asp:tablerows to be able to get or set the text in a textbox that is nested in the third cell of the row; I'm doing this by type rather than by ID because the cell ID's in that column aren't totally consistent--thus I can't really call FindControl() to achieve this. I've resorted to casting the third control in the TableRow to a TableCell and then Casting the first control in that cell to a TextBox. Not quite correct, as I'm getting an index out of range exception thrown. The problem mainly lies in the Controls.Count() property of the third cell, which comes to zero.

Not sure if there's a better way to access the textbox---should I resort to FindControl()?

The code:

foreach (TableRow row in tblProviders.Rows) {

    string value = ((TextBox)((TableCell)row.Controls(2)).Controls(0)).Text;

    ...


}

My searches here only yielded use of FindControl(), so that may be the only way...

Thanks!


Solution 1:

You could use Linq as follows:

var TextBoxes = tblProviders.Rows.OfType<TableRow>()
                            .SelectMany(row => row.Cells.OfType<TableCell>()
                            .SelectMany(cell => cell.Controls.OfType<TextBox>()));

TextBoxes would then be a collection of all the textboxes in tblProviders.Rows, which you could then itterate through and do what you like with.

Solution 2:

A little bit of null checking wouldn't go amiss here.

You could try using this Recursive call:

    foreach (TableRow row in tblProviders.Rows) {
        var tb = FindControlRecursive(row, typeof(TextBox));
        if (tb != null) {
           string value = ((TextBox)tb).Text;
        }
    }

    private Control FindControlRecursive(Control rootControl, Type controlType) {
        if (rootControl.GetType() == controlType) 
            return rootControl; //Found it

        foreach (Control controlToSearch in rootControl.Controls) {
            Control controlToReturn = FindControlRecursive(controlToSearch, controlType);
            if (controlToReturn != null) return controlToReturn;
        }
        return null;
    }