0

I have a html table on a page:

<table id="tblMain" runat="server" style="margin-left: auto; margin-right: auto;">
    <tr>
        <td>
            Safety
        </td>
        <td>
            <asp:TextBox ID="txtSafety" Width="400px" ReadOnly="true" TextMode="MultiLine" runat="server"></asp:TextBox>
        </td>
        <td>
            <asp:Button ID="btnSafety" runat="server" Width="150px" Text="Edit" 
                OnClick="Edit_Text" CommandArgument="0" />
        </td>
    </tr>
    <tr>
        <td>
            Environment
        </td>
        <td>
            <asp:TextBox ID="txtEnvironment" Width="400px" ReadOnly="true" TextMode="MultiLine" runat="server"></asp:TextBox>
        </td>
        <td>
            <asp:Button ID="bntEnvironment" Width="150px" runat="server" Text="Edit" 
                OnClick="Edit_Text" CommandArgument="1" />
        </td>
    </tr>
    <tr>
        <td>
            Quality
        </td>
        <td>
            <asp:TextBox ID="txtQuality" Width="400px" ReadOnly="true" TextMode="MultiLine" runat="server"></asp:TextBox>
        </td>
        <td>
            <asp:Button ID="btnQuality" Width="150px" runat="server" Text="Edit" 
                OnClick="Edit_Text" CommandArgument="2" />
        </td>
    </tr>
    <tr>
        <td>
            Ferrous System
        </td>
        <td>
            <asp:TextBox ID="txtFerrousSystem" Width="400px" ReadOnly="true" TextMode="MultiLine"
                runat="server"></asp:TextBox>
        </td>
        <td>
            <asp:Button ID="btnFerrousSystem" Width="150px" runat="server" Text="Edit" 
                OnClick="Edit_Text" CommandArgument="3" />
        </td>
    </tr>
    <tr>
        <td>
            Coke System
        </td>
        <td>
            <asp:TextBox ID="txtCokeSystem" Width="400px" ReadOnly="true" TextMode="MultiLine"
                runat="server"></asp:TextBox>
        </td>
        <td>
            <asp:Button ID="btnCokeSystem" Width="150px" runat="server" Text="Edit" 
                OnClick="Edit_Text" CommandArgument="4" />
        </td>
    </tr>
    <tr>
        <td>
            Coal Yards
        </td>
        <td>
            <asp:TextBox ID="txtCoalYards" Width="400px" ReadOnly="true" TextMode="MultiLine"
                runat="server"></asp:TextBox>
        </td>
        <td>
            <asp:Button ID="btnCoalYards" Width="150px" runat="server" Text="Edit" 
                OnClick="Edit_Text" CommandArgument="5" />
        </td>
    </tr>
    <tr>
        <td>
            Screenhouse
        </td>
        <td>
            <asp:TextBox ID="txtScreenhouse" Width="400px" ReadOnly="true" TextMode="MultiLine"
                runat="server"></asp:TextBox>
        </td>
        <td>
            <asp:Button ID="btnScreenhouse" Width="150px" runat="server" Text="Edit" 
                OnClick="Edit_Text" CommandArgument="6" />
        </td>
    </tr>
    <tr>
        <td>
            Process Plant
        </td>
        <td>
            <asp:TextBox ID="txtProcessPlant" Width="400px" ReadOnly="true" TextMode="MultiLine"
                runat="server"></asp:TextBox>
        </td>
        <td>
            <asp:Button ID="btnProcessPlant" Width="150px" runat="server" Text="Edit" 
                OnClick="Edit_Text" CommandArgument="7" />
        </td>
    </tr>
    <tr>
        <td>
            New Mill
        </td>
        <td>
            <asp:TextBox ID="txtNewMill" Width="400px" ReadOnly="true" TextMode="MultiLine" runat="server"></asp:TextBox>
        </td>
        <td>
            <asp:Button ID="btnNewMill" Width="150px" runat="server" Text="Edit" 
                OnClick="Edit_Text" CommandArgument="8" />
        </td>
    </tr>
    <tr>
        <td>
            Streamphases
        </td>
        <td>
            <asp:TextBox ID="txtStreamphases" Width="400px" ReadOnly="true" TextMode="MultiLine"
                runat="server"></asp:TextBox>
        </td>
        <td>
            <asp:Button ID="btnStreamphases" Width="150px" runat="server" Text="Edit" 
                OnClick="Edit_Text" CommandArgument="9" />
        </td>
    </tr>
    <tr>
        <td>
            Furnace Silos Injection
        </td>
        <td>
            <asp:TextBox ID="txtFurnaceSilosInjection" Width="400px" ReadOnly="true" TextMode="MultiLine"
                runat="server"></asp:TextBox>
        </td>
        <td>
            <asp:Button ID="btnFurnaceSilosInjection" Width="150px" runat="server" Text="Edit"
                OnClick="Edit_Text" CommandArgument="10" />
        </td>
    </tr>
    <tr>
        <td>
            CompressedAir
        </td>
        <td>
            <asp:TextBox ID="txtCompressedAir" Width="400px" ReadOnly="true" TextMode="MultiLine"
                runat="server"></asp:TextBox>
        </td>
        <td>
            <asp:Button ID="btnCompressedAir" Width="150px" runat="server" Text="Edit" 
                OnClick="Edit_Text" CommandArgument="11" />
        </td>
    </tr>
    <tr>
        <td>
            Planned Maintenance
        </td>
        <td>
            <asp:TextBox ID="txtPlannedMaintenance" Width="400px" ReadOnly="true" TextMode="MultiLine"
                runat="server"></asp:TextBox>
        </td>
        <td>
            <asp:Button ID="btnPlannedMaintenance" Width="150px" runat="server" Text="Edit" 
                OnClick="Edit_Text" CommandArgument="12" />
        </td>
    </tr>
    <tr>
        <td>
            Notifications Raised
        </td>
        <td>
            <asp:TextBox ID="txtNotificationsRaised" Width="400px" ReadOnly="true" TextMode="MultiLine"
                runat="server"></asp:TextBox>
        </td>
        <td>
            <asp:Button ID="btnNotificationsRaised" Width="150px" runat="server" Text="Edit"
                OnClick="Edit_Text" CommandArgument="13" />
        </td>
    </tr>
    <tr>
        <td>
            Manning
        </td>
        <td>
            <asp:TextBox ID="txtManning" Width="400px" ReadOnly="true" TextMode="MultiLine" runat="server"></asp:TextBox>
        </td>
        <td>
            <asp:Button ID="btnManning" Width="150px" runat="server" Text="Edit" 
                OnClick="Edit_Text" CommandArgument="14" />
        </td>
    </tr>
    <tr>
        <td>
            ShiftHandover
        </td>
        <td>
            <asp:TextBox ID="txtShiftHandover" Width="400px" ReadOnly="true" TextMode="MultiLine"
                runat="server" OnClick="Edit_Text"></asp:TextBox>
        </td>
        <td>
            <asp:Button ID="btnShiftHandover" Width="150px" runat="server" Text="Edit" 
                OnClick="Edit_Text" CommandArgument="15" />
        </td>
    </tr>
</table>

When the button is pressed the following method is called:

protected void Edit_Text(object sender, EventArgs e)
{
    Button btn = sender as Button;
    if (btn != null)
    {
        editField = btn.ID.Replace("btn", "");
        btn.Visible = false;
        //Getting and storing rowindex

        TextBox txt = this.FindControl("txt" + editField) as TextBox;
        txt.ReadOnly = false;
        txt.BackColor = System.Drawing.ColorTranslator.FromHtml("#FFFFB2");
        txt.Focus();
        comment = txt.Text;
        //Further methods unnecessary for this question
    }
}

As you can see, the prefix is stripped from the controls and then added in when necessary to find the right control at the point, therefore the string for the FindControl method is correct and should return a a TextBox.

However, by stepping through I can see that it is passing an empty TextBox instance rather than the expected result or a null.

I have already tried the findcontrol function on the table itself, I used 'this' as a second check but both yielded the same results.


I suspect the html table is a problem as in another method I am having issues finding a button manually in the html table:

Button editbtn = tblMain.Rows[GetRowIndex(hdnRowIndex.Value)].Cells[2].Controls[0] as Button;

Which is returning a null despite there always being a cell button in that cell for each row

EDIT - Here is the binding that is performed

private void bindData(DataTable dt)
{
    if (dt.Rows.Count > 0)
    {
        foreach (DataColumn col in dt.Columns)
        {
            TextBox txt = tblMain.FindControl("txt" + col.ColumnName) as TextBox;
            if (txt != null)
            {
                txt.Text = dt.Rows[0][col].ToString();
            }
        }
    }
}
5
  • Your table isn't generated via some sort of DataBound control like a GridView, Repeater, or a ListView, is it? Commented May 14, 2015 at 12:43
  • couldn't you use the object sender as Button ? Commented May 14, 2015 at 12:46
  • No it is a html table, each row being similar to the one shown. There is data being bound to it, but that is being done to each textbox in turn by looping a datatable and establishing the textbox from the field name. I shall append it to the question Commented May 14, 2015 at 12:48
  • So your button is null? Or the text box? Title suggest the former but description says the latter Commented May 14, 2015 at 12:48
  • i see the confusion, sorry Andrei, i made a typo and wrote button instead of textbox in the middle of the question. I shal ledit Commented May 14, 2015 at 12:53

2 Answers 2

1

Your problem is here:

this.FindControl("txt" + editField) as TextBox;

FindControl is not recursive and can only find immediate children of the control it was called on. Here you are calling it of the page instance, so it only seeks through immediate children of the page in the control tree (presumably this is only a form element).

What you need to do is to pick a server-side control right above your textboxes/buttons and run FindControl of it. For instance, let's say it is your table, which is declared as:

<table>
<%--...all the content from the post goes here...--%>
</table>

Make this table server-side:

<table id="TheTable" runat="server">

and then call FindControl on this table:

TextBox txt = TheTable.FindControl("txt" + editField) as TextBox;

You can of course keep the table client-side, and use some control that wraps this table. Just make sure that in between your control and the textbox in question there are no other server-side controls.

Sign up to request clarification or add additional context in comments.

7 Comments

Sorry I never mentioned, I tried this first then resorted to THIS as a way of checking. Using this method poses the same results
@nickson104, that's really strange. Can you please post the markup of the whole table? You can still leave just one row, I am more interested in the table declaration
I agree, very interesting :-)
Table has been added. I cant quite put my finger on the issue
Can you try to remove the runat = server from the table and always call this.FindControl? I don't see the use for it
|
0
 <table style="width:100%; margin-left:auto; margin-right:auto;" id="tblTst" runat="server">
        <tr>
            <td>
                <h2>
                    Vehicle Information
                    <asp:Label ID="lblTest" Text="THis is a Test" ForeColor="Salmon" runat="server" />
                    <asp:Button ID="btnTest" CommandArgument="0" OnClick="btnTest_click" runat="server" Text="Test" />
                </h2>
            </td>
        </tr>
        <tr>
            <td>
                    <asp:Label ID="lblTst2" Text="This is also a Test" ForeColor="Salmon" runat="server" />
                    <asp:Button ID="btnTest2" CommandArgument="1" OnClick="btnTest_click" runat="server" Text="Test" />

            </td>
        </tr>
        <tr>
            <td>
                <asp:Label ID="lblMsg" runat="server" />
            </td>
        </tr>
    </table>


    protected void btnTest_click(object sender, EventArgs e)
{
    Button btn = sender as Button;
    string comment = "";
    string editField = "";
    if (btn != null)
    {
        editField = btn.ID.Replace("btn", "");
        btn.Visible = false;
        //Getting and storing rowindex
        foreach(HtmlTableCell cl in tblTst.Rows[Convert.ToInt32(btn.CommandArgument)].Cells)
        {
            foreach (Control ctrl in cl.Controls)
            {
                if(ctrl is Label)
                {
                    Label txt = new Label();
                    txt = ctrl as Label;
                    txt.BackColor = System.Drawing.ColorTranslator.FromHtml("#FFFFB2");
                    txt.Focus();
                    comment = txt.Text;
                    lblMsg.Text = comment;
                    return;
                }
            }
        }
        //Further methods unnecessary for this question
    }
}

}

This is what I came up with, this does work; however it is a fairly dirty way to do this, I'm sure you can clean it up quite a bit. This is only intended as a starting point. The big different is that you need to look in the cell for the control not in the table or page, also the cell is an htmltable cell not just a table cell.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.