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();
}
}
}
}
您的问题在这里:
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单元格,而不仅仅是一个表单元格。