Using a CheckBoxList with ViewState turned on would cover the second part. Setting the value of the ListItem in the CheckBoxList to something like the name of the bit column would make it easy to use cbl.Items.FindByValue("colName").Checked = colValue and colValue = cbl.Items.FindByValue("colName").Checked to load and save the state.
EDIT: If you must use the StringBuilder approach
The quick and dirty way is to just build the markup and set the values as you loop through the record set making sure that, on post back, you save the value to the DB before you read the values from it. If you mix up the save/load order the db will update but the user will see the old values when the page refreshes, and if they hit save again they'll overwrite the new values with the old.
If you need to lighten the load on the db, then on post back [i.e. if(Page.IsPostBack)] load the values from Request.Form["chkBxName"] instead.
I don't think there's a very slick way of doing it without building your own ViewState like framework.