Question

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?

Page LoadAfter "Go!"

*.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
Was it helpful?

Solution 2

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

OTHER TIPS

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++;
                }
            }
        }

you should try EnableViewState="True" property at @page as follow:

<%@ Page Language="C#" Inherits="LunaIntraDB.sandbox" 
MasterPageFile="~/SiteMaster.master" 
EnableViewState="True"
%>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top