FindControl返回空的文本框对象/null

本文关键字:对象 null 文本 返回 FindControl | 更新日期: 2023-09-27 17:49:15

我在一个页面上有一个html表:

<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>

按下按钮时,将调用以下方法:

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
    }
}

正如您所看到的,前缀从控件中剥离,然后在必要时添加,以在该点找到正确的控件,因此FindControl方法的字符串是正确的,应该返回一个TextBox。

然而,通过逐步查看,我可以看到它传递的是一个空的TextBox实例,而不是预期的结果或null。

我已经在表本身上尝试了findcontrol函数,我使用"this"作为第二次检查,但两者都产生了相同的结果。


我怀疑html表是个问题,因为在另一种方法中,我在html表中手动查找按钮时遇到问题:

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

它返回一个null,尽管每行的单元格中总是有一个单元格按钮

EDIT-这是执行的绑定

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();
            }
        }
    }
}

FindControl返回空的文本框对象/null

您的问题在这里:

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

FindControl不是递归的,只能找到它被调用的控件的直接子级。这里是页面实例的调用,所以它只在控件树中搜索页面的直接子代(可能这只是一个表单元素(。

你需要做的是在你的文本框/按钮上方选择一个服务器端控件,并运行它的FindControl。例如,假设它是你的表,声明为:

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

将此表设置为服务器端:

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

然后调用此表上的FindControl:

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

当然,您可以将表保留在客户端,并使用一些封装该表的控件。只需确保在您的控件和有问题的文本框之间没有其他服务器端控件。

 <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
    }
}

}

这就是我想到的,这确实有效;然而,这是一种相当肮脏的方法,我相信你可以把它清理干净。这只是一个起点。最大的不同是,您需要在单元格中查找控件,而不是在表或页中,而且该单元格是一个htmltable单元格,而不仅仅是一个表单元格。