Question

To ask my question I have created an aspx file containing a Button and a DataList with an SqlDataSource:

    <asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />

    <asp:DataList ID="DataList1" runat="server" DataKeyField="a" 
    DataSourceID="SqlDataSource1" >
        <ItemTemplate>
            a:
            <asp:Label ID="aLabel" runat="server" Text='<%# Eval("a") %>' />
            <br />
            b:
            <asp:Label ID="bLabel" runat="server" Text='<%# Eval("b") %>' />
            <br />
        </ItemTemplate>
    </asp:DataList>

<asp:SqlDataSource ID="SqlDataSource1" runat="server" 
    ConnectionString="<%$ ConnectionStrings:probaConnectionString %>" 
    SelectCommand="SELECT [a], [b] FROM [PROBA_TABLE]"></asp:SqlDataSource>

In my code behind I add TextBoxes to the Items of the DataList. I add to every Item a TextBox in the Page_Load, and another TextBox in the Button Click eventhandler as well.

    public partial class _Default : System.Web.UI.Page
    {   
        protected void Page_Load(object sender, EventArgs e)
        {
            if (IsPostBack)
            {
                foreach (DataListItem item in DataList1.Items)
                {
                    item.Controls.Add(new TextBox());
                }
            }
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            foreach (DataListItem item in DataList1.Items)
            {
                item.Controls.Add(new TextBox());
            }
        }

    }
}

This works fine except one thing. When I click the Button, the TextBoxes which were created in the Page_Load keep their Text value, but the TextBoxes which were created in the Button1_Click lose their Text values. My real problem is more complicated than this, but I think solving this would help me a lot.

My site after postback

Was it helpful?

Solution

Each control that should receive data from page ViewState should be instantiated in Init or Load event handlers, because ViewState is persisted to controls BEFORE Click, Change and the rest control events (those events are triggered when ViewState changes are detected, so ViewState must be read before Click event is fired).

So the process should look like:

  1. OnInit (static controls get created)
  2. Static control content is deserialized from ViewState
  3. OnLoad (create dynamic controls, in your case textboxes that you created in last Postback)
  4. Dynamic control content is deserialized from ViewState
  5. Click, Change and other events are fired according to changes detected comparing POST data and ViewState data

Suggestions:

You can use hidden fields to save additional status information, and then in OnLoad you can read that info to recreate dynamically created controls.

Also, you should explicitly set ID property of your textboxes so that values can be properly persisted back, don't rely on ASP.Net.

OTHER TIPS

the http by default is stateless that means after your request is processed the server keeps no data or info of the request
but the values in the form need to be persisted in special cases when there is an error

suppose you fill up a long form and then post it back to the server only to get an error message and all the filled up values are gone. wouldn't that be annoying

so what asp.net does behind the scenes that it keeps a string in the page hidden that has information about all the server controls and their ids
so when you post a form back the Page class is created and the values that are posted back and binded in the specific controls
because the Page class is being created in every request the pageLoad event is run and controls created in the PageLoad are then present values corresponding to their ids are put into them
unlike the controls that are being created on button click
till the button_click event is run that viewstate has already been deseralized and values are filled into them

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top