Every 3 or 4 months I build a website that uses a list of check boxes to allow the users to make a selection from a list of items.
Every 3 or 4 months I fight, curse, and swear at ASP.Net and its databound controls (okay, I don't curse or swear but I do fight).
So, I've just finished doing it all again and this time I'm going to write it down so I don't forget how it's "supposed to be done".
I have a list of thingies that I want the user to choose from. I list the thingies out in a repeating control (I use the asp:repeater but a asp:datalist behaves the same).
The user checks off the items they want and clicks a button firing off a server side onClick event.
You loop through all the check box controls and none of them are checked. A secondary problem is that the asp:checkbox control does not have a "Value" property to store useful information about what the checkbox might be tied to.
After searching the Google for help and only finding posts from 2003 I figured that either everyone gave up or this isn't really a problem for anyone but me.
One search hit suggested that I make sure I DataBind my repeater on every post back (in other words, don't put my data binding inside the !Page.IsPostback block of my Page_Load). This didn't work.
Someone suggested creating a hidden control to store a Value (since asp:checkbox doesn't have a value property), but doesn't really seem to address the issue of all the checkbox check states missing when you post back.
I found a suggestion that said making the itemcommand event trigger and then looping through the all items on the repeater would work. I think this method would allow you to get the dataitem associated with the checkbox and might preserve the check states. However, I wasn't able to get something workable using this technique. And it feels a bit wrong to use itemcommand which is intended for a single "row" or item and apply it for the entire repeater.
So the solution I found is to use the HtmlInputCheckbox control instead of the asp:Checkbox control. It really is that simple. It has a Value property and it maintains its checked value after the postback.
To retrieve the check states and values simply loop through each item in the repeater and get the html input check box using FindControl. Do this before re-binding the repeater.
Example (ASP.Net 2.0)