ASP.NET checkbox incorrect value on postback
<p>I am having an issue with some of my dynamic checkboxes on a project I am working on. </p>

<p>I have a tables, and in one cell per row, I have a checkbox. This checkbox is checked to "flag" that record. The records in the table are populated on a button click, after the user has set a series of filters. Therefore, the table contents completely change on each postback. </p>

<p>I use a list to preserve which records were already flagged, so that if a record appears that was previously checked, it will be checked on that retrieval too. </p>

<p>I am performing this check against my list in my <code>page_load</code> function and I can see through debugging that it is getting set correctly. However, when the page is done loading, the checked status is often wrong. </p>

<p><strong>Do I need to move my checkbox state verification step to another part of the page lifecycle?</strong> </p>

<p>Any tips would be great. I found some questions on asp.net issues with checkboxes, but I they did not seem to be relevant to my issue.</p>

<p>Here is the code, feel free to critique any/all of it :)</p>

<pre><code>using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace ScienceAssessmentToolASP
{
    public partial class createnewtest : System.Web.UI.Page
    {
    private int n;
    private SqlConnection conn = null;
    private List&lt;int&gt; flaggedQuestions = new List&lt;int&gt;();

    protected void Page_Load(object sender, EventArgs e)
    {

        if (IsPostBack)
        {
            var temp = (List&lt;int&gt;)Session["flaggedQuestions"];
            if (temp != null)
                flaggedQuestions = temp; ;//retrieve flags from session
            try
            {
                GetConn();
                ExecuteRetrieval();

                n = 1;
            }
            catch (Exception ex) { n = 0; Response.Write("for debugging: " + ex); }
            finally { if (conn != null) conn.Close(); }
            if (n &lt; 0)
                //Label1.Text = "Connection Successful";
                Label3.Text = "Failed to Connect to Database, please contact the administrator.";
        }
    }

    protected void Button1_Click(object sender, EventArgs e)
    {  
    }

    private void GetConn()
    {
        string connString = @"laalalala";


        conn = new SqlConnection(connString);
        conn.Open();
    }

    private void ExecuteRetrieval()
    {
        SqlDataReader reader = null;
        string query;

        if (!IsPostBack)
        {
            query = "select * from [ScienceQA]";
            flaggedQuestions = (List&lt;int&gt;)Session["flaggedQuestions"];//retrieve flags from session
        }
        else query = "select * from [ScienceQA] where [GradeLevel] = " + DropDownList1.Text +
            " and [Topic] = '" + DropDownList2.Text + "';";

        SqlCommand cmd = new SqlCommand(query, conn);

        reader = cmd.ExecuteReader();

        TableHeaderRow headerRow = new TableHeaderRow();
        TableHeaderCell idH = new TableHeaderCell();
        TableHeaderCell questionH = new TableHeaderCell();
        TableHeaderCell answerH = new TableHeaderCell();
        TableHeaderCell flagH = new TableHeaderCell();

        idH.Text = "ID";
        questionH.Text = "Question";
        answerH.Text = "Answer";
        flagH.Text = "Flag";

        headerRow.Cells.Add(idH);
        headerRow.Cells.Add(questionH);
        headerRow.Cells.Add(answerH);
        headerRow.Cells.Add(flagH);
        resultTable.Controls.Add(headerRow);

        while (reader.Read())
        {
            TableRow row = new TableRow();
            TableCell idCell = new TableCell();
            TableCell qCell = new TableCell();
            TableCell aCell = new TableCell();
            TableCell flag = new TableCell();

            idCell.Text = reader[0].ToString();
            qCell.Text = reader[1].ToString();
            aCell.Text = reader[2].ToString();

            CheckBox flagBox = new CheckBox();
            int id = Convert.ToInt32(idCell.Text);
            flagBox.AutoPostBack = true;
            flagBox.CheckedChanged += new System.EventHandler(flagButton_Click);
            flagBox.EnableViewState = true;
            flagBox.ViewStateMode = ViewStateMode.Enabled;

            if (flaggedQuestions.Contains(id) &amp;&amp; flagBox.ID == "flag" + id)
                flagBox.Checked = true;
            else flagBox.Checked = false;

            flagBox.Text = id.ToString();
            flag.Controls.Add(flagBox);

            row.Cells.Add(idCell);
            row.Cells.Add(qCell);
            row.Cells.Add(aCell);
            row.Cells.Add(flag);
            resultTable.Controls.Add(row);          
        }

        Label4.Visible = true;
        flagCounter.Visible = true;
        resultTable.Visible = true;
    }


    protected void flagButton_Click(object sender, EventArgs e) 
    {
        CheckBox lb = (CheckBox)sender;
        int questionID = Convert.ToInt32(lb.ID.Substring(4));


        if (lb.Checked &amp;&amp; !flaggedQuestions.Contains(questionID))  
        {
            //lb.Checked = false;
            flaggedQuestions.Add(questionID);
            flagCounter.Text = Convert.ToString(flaggedQuestions.Count);
        }
        else
        {
            //lb.Checked = true;
            flaggedQuestions.Remove(questionID);
            flagCounter.Text = Convert.ToString(flaggedQuestions.Count);
        }
        Session["flaggedQuestions"] = flaggedQuestions;//store questions to session
    }

    protected void createTestButton_Click(object sender, EventArgs e)
    {
        //create a test
        bool sendQuery = true;
        string author = Session["user"].ToString();
        string accessLevel = accessDropdown.Text;
        int gradeLevel = Convert.ToInt32(DropDownList1.Text);
        int questionCount = flaggedQuestions.Count();
        string testType = testTypeDropDown.Text;
        string description = descriptionBox.Text;

        string questionString = "";

        for (int i = 0; i &lt; flaggedQuestions.Count(); i++)
            questionString += flaggedQuestions[i] + ",";

        string query = @"Insert into Tests Values ('" + author + "','" + questionString
             + "','" + accessLevel + "','" + gradeLevel + "','" + questionCount + "','"
              + testType + "','" + description +"');";

        //check parameters
        if (accessLevel == "")
        {
            errorLabel.Text = "Please choose an access level.";
            sendQuery = false;
        }
        if (questionCount == 0)
        {
            errorLabel.Text = "Please flag a set of questions before creating a test.";
            sendQuery = false;
        }
        if (testType == "")
        {
            errorLabel.Text = "Please choose a test type";
            sendQuery = false;
        }
        if (description == "")
        {
            errorLabel.Text = "Please describe your test";
            sendQuery = false;
        }
        if (sendQuery)
        {

            try
            {
                GetConn();
                SqlCommand cmd = new SqlCommand(query, conn);
                cmd.Prepare();
                int n; 
                n = cmd.ExecuteNonQuery();
            }
            catch (Exception e2) { n = 0; }

            if (n == 1)
                errorLabel.Text = "Test Created Successfully";
            else errorLabel.Text = "Test Creation Failed, please check your parameters.";
        }
    }

}
}
</code></pre>

<p>Here was the solution that worked for me, moving the checkbox state check to the onprerender function. </p>

<pre><code>        protected override void OnPreRender(EventArgs e)
    {
        foreach (TableRow row in resultTable.Rows)
        {
            var cell = row.Cells[3];
            foreach (Control control in cell.Controls)
            {
                var flagBox = control as CheckBox;
                if (flagBox != null)
                {
                    int id = Convert.ToInt32(flagBox.ID.Substring(4));
                    if (flaggedQuestions.Contains(id) &amp;&amp; flagBox.ID == "flag" + id)
                        flagBox.Checked = true;
                    else flagBox.Checked = false;
                }
            }
        }
    }
</code></pre>
