简体   繁体   中英

FindControl() always returns null from DataList Textbox

I have 8 items in a SQL table with a Description, ItemNumber, and ImagePath.

protected void Page_Load(object sender, EventArgs e)
    {
        //fill the datalist for the Signs Table
        string tCallFrom = "Program." + System.Reflection.MethodBase.GetCurrentMethod().Name;
        string tQry = @"SELECT * FROM [js_Signs]";

        DataTable tblSigns = objCommMethods.fReturnTableFromQry(clsDBSelect.enumDBSelect.ProjectMaster, tQry, tCallFrom);

        SignsList.DataSource = tblSigns;
        SignsList.DataBind();
    }

I am using a DataList to show all of the items along with a textbox that will allow a user to input the number of items they want:

    <asp:DataList ID="SignsList" runat="server" RepeatColumns="4" CellPadding="2" Width="90%" ItemStyle-HorizontalAlign="Center">
                        <ItemTemplate>
                            <table>
                                <tr>
                                    <th>
                                       <%#DataBinder.Eval(Container.DataItem, "Description") %>
                                    </th>
                                </tr>
                                 <tr>
                                    <th>
                                    <%#DataBinder.Eval(Container.DataItem, "ItemNumber") %>
                                    </th>
                                </tr>
                                <tr>
                                    <td>
                                        <asp:Image ID="SignImage" runat="server" ImageUrl='<%#DataBinder.Eval(Container.DataItem, "ImagePath") %>' />
                                    </td>
                                </tr>
                                <tr style="text-align: center;">
                                    <td>
                                        <asp:TextBox ID="txtSignQuantity" runat="server" CssClass="txtBox" BackColor="White" Enabled="true" 
                                            type="number" min="0" ToolTip="Please choose quantity of signs needed."/>
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        <p> </p>
                                    </td>
                                </tr>
                            </table>
                        </ItemTemplate>
                    </asp:DataList>
             <div class="btnGroup">
                <div class="btnDiv">
                    <asp:Button ID="btnSave" runat="server" Text="Save" CssClass="btnSave" Width="90px" Visible="true" OnClick="btnSave_Click"/>
                </div>
                <div class="btnDiv">
                    <asp:Button ID="btnCancel" runat="server" Text="Clear" CssClass="btnCancel" Width="90px" Visible="true" OnClick="btnCancel_Click"/>
                </div>
            </div>

After the saved button is clicked in C# I want to find out the value that a user entered but it is always returning null:

protected void btnSave_Click(object sender, EventArgs e)
{
        TextBox txtSignQuantity;
        string tempSignQuantity;
        try
        {
            foreach (DataListItem item in SignsList.Items)
            {
                txtSignQuantity = item.FindControl("txtSignQuantity") as TextBox;
                tempSignQuantity = txtSignQuantity.Text;
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }   
}

I also checked and the Count of SignsList.Items was 8, so I know that it is retrieving the correct information. Sorry, I've never used a Data List before so I'm not really sure how to go about this...

The short answer is that data binding on postback is causing the problem. Check the Page.IsPostBack property before doing data binding:

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        //fill the datalist for the Signs Table
        string tCallFrom = "Program." + System.Reflection.MethodBase.GetCurrentMethod().Name;
        string tQry = @"SELECT * FROM [js_Signs]";
        DataTable tblSigns = objCommMethods.fReturnTableFromQry(clsDBSelect.enumDBSelect.ProjectMaster, tQry, tCallFrom);

        SignsList.DataSource = tblSigns;
        SignsList.DataBind();
    }
}

ASP.NET WebForms attempts to abstract away the fact that the control instances that were used to render the page are not the same instances it has when handling postback events. Data binding compounds the abstraction because it has to create controls in response to the DataBind call, and then on postback, recreate them based on the ViewState it saved.

Initializing controls from ViewState happens on the Init event, so when the Load event is fired later in the page lifecycle and you call DataBind on the control, everything it restored gets wiped out and recreated.

As for why you were getting null , it may have been that the controls were wiped out but not recreated; it may have had to do with other event handlers that didn't get rewired after the second data binding.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM