1

I have the following code :

   Label docsLabel = new Label();
   docsLabel = (Label)tasksPlaceholder.FindControl("taskdocs_" + taskId);
   int index = tasksPlaceholder.Controls.IndexOf(docsLabel);

The label is found within the placeholder, but when I call .IndexOf() it always returns -1.

How do I find the correct position of this control?

Dharmesh
  • 132
  • 1
  • 12
Andre J
  • 227
  • 4
  • 18
  • Why do you use `new Label()` at all when you use `FindControl` one line later anyway? This is just confusing and does nothing. – Tim Schmelter Feb 20 '14 at 11:21
  • Probably because the label is not a direct child of the placeholder. – Candide Feb 20 '14 at 11:21
  • Does the `(Label)tasksPlaceholder.FindControl("taskdocs_" + taskId);` really find the control? Don't you passing null to `IndexOf()`? – rocky Feb 20 '14 at 11:26
  • It does find the control, but its not a direct child of the placeholder. – Andre J Feb 20 '14 at 11:27
  • @AndreJ, then you cannot expect it to be in the placeholder's controls collection. – Andrei Feb 20 '14 at 11:30
  • Well then its just silly that .FindControl() can find it but cannot be found with .indexOf(). Thanks anyways, will make a plan – Andre J Feb 20 '14 at 11:32
  • Is this really the original code or is it simplified? – Tim Schmelter Feb 20 '14 at 11:43
  • Just a thought, if indexof is not working then you can loop through the controls collection of the placeholder and check for reference equality. Simultaneously you can set a counter and increase it by 1 as you keep on checking. Not very sure if this will give you the correct index though. – samar Feb 20 '14 at 11:50
  • Its the original code, the element I want to update is 3 levels down (TableRow -> TableCell ->Label – Andre J Feb 20 '14 at 11:52
  • Thanks @samar, will give it a try. I just want to update the text of the control, seems like its not easy to do if its in a placeholder – Andre J Feb 20 '14 at 11:53
  • Another way could be writing a recursive function to check for child controls within a control but then you would need to be careful about the counter as it might increment unnecessarily on recursion. – samar Feb 20 '14 at 11:55

1 Answers1

1

This is an important information in your comments:

the element I want to update is 3 levels down (TableRow -> TableCell ->Label)

Control.FindControl finds all control in this NamingContainer whereas ControlCollection.IndexOf finds only controls in this control. So if this control contains for example a table which contains rows and cells and every cell contains also controls, all of these controls will not be found by IndexOf, only the top-control is searched.

Control.FindControl will search all controls that belong to this NamingContainer(a control that implements INamingContainer). A table/row/cell does not implement it, that's why all of these controls are also searched with FindControl.

However, FindControl will not search through sub-NamingContainers (like a GridView in a GridViewRow).

This reproduces your issue:

protected void Page_Init(object sender, EventArgs e)
{
    // TableRow -> TableCell ->Label
    var table = new Table();
    var row = new TableRow();
    var cell = new TableCell();
    var label = new Label();
    label.ID = "taskdocs_1";
    cell.Controls.Add(label);
    row.Cells.Add(cell);
    table.Rows.Add(row);
    tasksPlaceholder.Controls.Add(table);
}

protected void Page_Load(object sender, EventArgs e)
{
    Label docsLabel = (Label)tasksPlaceholder.FindControl("taskdocs_1");
    int index = tasksPlaceholder.Controls.IndexOf(docsLabel); 
    // docsLabel != null and index = -1 --> quod erat demonstrandum
}

How do I find the correct position of this control?

If you want to find the row-number this label belongs to:

Label docsLabel = (Label)tasksPlaceholder.FindControl("taskdocs_1");
TableRow row = (TableRow)docsLabel.Parent;
Table table = (Table)row.Parent;
int rowNumber = table.Rows.GetRowIndex(row);
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939