【问题标题】:FindControl returns empty textbox object / nullFindControl 返回空文本框对象 / null
【发布时间】:2015-05-14 12:40:32
【问题描述】:

我在页面上有一个 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

编辑 - 这是执行的绑定

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

【问题讨论】:

  • 您的表格不是通过某种 DataBound 控件(如 GridView、Repeater 或 ListView)生成的,是吗?
  • 你不能使用object sender作为按钮吗?
  • 不,它是一个 html 表,每一行都与所示的相似。有数据绑定到它,但这是通过循环数据表并从字段名称建立文本框依次对每个文本框完成的。我会将它附加到问题中
  • 所以你的按钮是空的?还是文本框?标题建议前者,但描述说后者
  • 我看到了混乱,对不起安德烈,我打错了字,在问题中间写了按钮而不是文本框。我会领导

标签: c# asp.net html-table findcontrol


【解决方案1】:

你的问题在这里:

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;

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

【讨论】:

  • 对不起,我从来没有提到过,我先尝试了这个,然后求助于这个作为一种检查方式。使用这种方法会产生相同的结果
  • @nickson104,这真的很奇怪。你能张贴整个表格的标记吗?还是可以只留一行,我对表声明比较感兴趣
  • 我同意,非常有趣:-)
  • 表已添加。我不能完全解决这个问题
  • 您可以尝试从表中删除 runat = 服务器并始终调用 this.FindControl 吗?我看不出它的用途
【解决方案2】:
 <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 单元格而不仅仅是一个表格单元格。

【讨论】:

    猜你喜欢
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    • 2013-09-20
    • 2012-08-18
    • 1970-01-01
    • 1970-01-01
    • 2011-10-28
    • 2012-01-25
    相关资源
    最近更新 更多