0
votes

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();
            }
        }
    }
}
2
Your table isn't generated via some sort of DataBound control like a GridView, Repeater, or a ListView, is it? - j.f.
couldn't you use the object sender as Button ? - leAthlon
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 - nickson104
So your button is null? Or the text box? Title suggest the former but description says the latter - Andrei
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 - nickson104

2 Answers

1
votes

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.

0
votes
 <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.