Q:

CheckboxList selections cleared on linkbutton click (despite postback check)

How are checkbox properties retrieved before they are cleared?
I'd like to count the number of checked boxes after clicking "Go!". Instead, after clicking, the boxes (even those that default to selected) are cleared and the count is zero.
Do I need another way of protecting the values from postback?
 
→ 

*.aspx
<%@ Page Language="C#" Inherits="LunaIntraDB.sandbox" MasterPageFile="~/SiteMaster.master" %>
<%@ MasterType VirtualPath="~/SiteMaster.master" %>
<asp:Content ContentPlaceHolderID="HeadContent" ID="HeadContentContent" runat="server">
</asp:Content>
<asp:Content ContentPlaceHolderID="MainContent" ID="MainContentContent" runat="server">

<asp:CheckBoxList ID="aCheckBoxList" runat="server" >
  <asp:ListItem Value="DontCheck" runat="server">1</asp:ListItem>
  <asp:ListItem Value="blah" Selected="True" runat="server">2</asp:ListItem>
</asp:CheckBoxList>

 <asp:LinkButton ID="goButton" runat="server" Text="Go!" onclick="Clicked" />

</asp:Content>

*.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using MySql.Data.MySqlClient;
using System.Data;
using System.Collections;

namespace LunaIntraDB
{

    public partial class sandbox : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack) {
                debugPrint("Load,beforeAdd");
                aCheckBoxList.Items.Add("Added 1");
                aCheckBoxList.Items.Add("Added 2");
                aCheckBoxList.Items.Add("Added 3");
                aCheckBoxList.Items[4].Selected = true;
                debugPrint("Load,addedItems");

            } else {
                debugPrint("PostBack");
            }
        }

        protected void Clicked(object sender, EventArgs e)
        {
            debugPrint("Button push");
        }

        /* Print Selected index and a count of selected checkboxes */
        protected void debugPrint(String where) {
            String count = aCheckBoxList.Items.Cast<ListItem>().Where(n => n.Selected).ToList().Count.ToString();
            System.Diagnostics.Debug.WriteLine(where +": "+ aCheckBoxList.SelectedIndex.ToString() + " =>" + count + "/"+ aCheckBoxList.Items.Count.ToString()  );
        }
    }
}

Console output

[0:] Load,beforeAdd: 1 =>1/2
[0:] Load,addedItems: 1 =>2/5
// check a bunch and click "Go!"
[0:] PostBack: -1 =>0/5
[0:] Button push: -1 =>0/5

Mono version
Mono JIT compiler version 3.2.3 (tarball Sun Sep 22 20:38:43 UTC 2013) Copyright (C) 2002-2012 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
        TLS:           __thread
        SIGSEGV:       altstack
        Notifications: epoll
        Architecture:  amd64
        Disabled:      none
        Misc:          softdebug 
        LLVM:          supported, not enabled.
        GC:            sgen

A:

Taken from http://www.strawberryfin.co.uk/blog/2012/08/22/dealing-with-dynamic-checkboxlists-losing-their-state-after-postback/
In Page_Load(object sender, EventArgs e):
setCheckBoxStates (aCheckBoxList);

elsewhere
public static void setCheckBoxStates(CheckBoxList cbl)
        {
            // if we are postback and using mono
            if (HttpContext.Current.Request.HttpMethod == "POST"  && Type.GetType("Mono.Runtime") != null)
            {
                string cblFormID = cbl.ClientID.Replace("_","$");
                int i = 0;
                foreach (var item in cbl.Items)
                {
                    string itemSelected = HttpContext.Current.Request.Form[cblFormID + "$" + i];
                    if (itemSelected != null && itemSelected != String.Empty)
                        ((ListItem)item).Selected = true;
                    i++;
                }
            }
        }

A:

Though @Will's answer in on the right track, it isn't conclusive of the entire issue.
For example, when a CheckBoxList is inside of Repeater control, the ClientID has a different format to indicate the CheckBoxList position inside the Repeater.
It's also safe to say that we don't really want to handle this issue for every use of a CheckBoxList, so I've created a custom control that extends the CheckBoxList.OnLoad event to resolve the issue outline above.
namespace YOURNAMESPACE.Controls
{
    using System.Text.RegularExpressions;
    using System;
    using System.Web;
    using WebControls = System.Web.UI.WebControls;

    public class CheckBoxList : WebControls.CheckBoxList
    {
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            if (HttpContext.Current.Request.HttpMethod == "POST" && Type.GetType("Mono.Runtime") != null) {

                string cblFormID = Regex.Replace(ClientID, @"_\d+$", String.Empty).Replace("_", "$");

                int i = 0;
                foreach (WebControls.ListItem item in Items)
                    item.Selected = HttpContext.Current.Request.Form[cblFormID + "$" + i++] == item.Value;
            }
        }
    }
}

