30

Is it possible to DataBind an ASP.NET CheckBoxList such that a string value in the data becomes the label of the check box and a bool value checks/unchecks the box?

On my asp.net webform I have a CheckBoxList like this:

<asp:CheckBoxList runat="server" ID="chkListRoles" DataTextField="UserName" DataValueField="InRole" />

In the code behind I have this code:

var usersInRole = new List<UserInRole> 
{ 
  new UserInRole { UserName = "Frank", InRole = false},
  new UserInRole{UserName = "Linda", InRole = true},
  new UserInRole{UserName = "James", InRole = true},
};

chkListRoles.DataSource = usersInRole;
chkListRoles.DataBind();

I was kinda hoping that the check boxes would be checked when InRole = true. I've also tried InRole = "Checked". The results were the same. I can't seem to find a way to DataBind and automagically have the check boxes checked/unchecked.

Currently I solve the problem by setting selected = true for the appropriate items in the DataBound event. Seems like there's a cleaner solution just beyond my grasp.

Thank You

Matthew Sposato
  • 1,635
  • 1
  • 11
  • 13
  • http://stackoverflow.com/questions/879434/asp-net-checkboxlist-databinding-question –  Mar 07 '15 at 17:06

5 Answers5

43

EDIT: There's no way to do this through the Markup. The DataValueField does not determine whether the checkbox item is check or not. It retrieves or stores the value to be used in postbacks. The DataValueField is common across CheckBoxLists, RadioButtonLists, ListControl, etc.

This is about the only way to pre-select the checkboxes as you already found out.

chkListRoles.DataSource = usersInRole;
chkListRoles.DataBind();

foreach(ListItem item in chkListRoles.Items)
 item.Selected = usersInRole.Find(u => u.UserName == item.Text).InRole;
Jose Basilio
  • 50,714
  • 13
  • 121
  • 117
10

I made a custom control for this, after getting tired of the OnItemDataBound-binding. It will let you bind the Selected attribute. You can easily make the same control for RadioButtonList by changing what the custom control derives from.

To use this, simply add the DataCheckedField attribute when you create the control in your markup. Remember to reference the custom controls in your web.config file.

Markup

<myControls:SimpleCheckBoxList runat="server" ID="chkListRoles"
                               DataCheckedField="InRole"
                               DataTextField="UserName"
                               DataValueField="UserId" />

Code for the control

public class SimpleCheckBoxList : System.Web.UI.WebControls.CheckBoxList
{
    public string DataCheckedField
    {
        get
        {
            string s = (string)ViewState["DataCheckedField"];
            return (s == null) ? String.Empty : s;
        }
        set
        {
            ViewState["DataCheckedField"] = value;
            if (Initialized)
                OnDataPropertyChanged();
        }
    }

    protected override void PerformDataBinding(IEnumerable dataSource)
    {
        if (dataSource != null)
        {
            if (!this.AppendDataBoundItems)
                this.Items.Clear();

            if (dataSource is ICollection)
                this.Items.Capacity = (dataSource as ICollection).Count + this.Items.Count;

            foreach (object dataItem in dataSource)
            {
                ListItem item = new ListItem()
                {
                    Text = DataBinder.GetPropertyValue(dataItem, DataTextField).ToString(),
                    Value = DataBinder.GetPropertyValue(dataItem, DataValueField).ToString(),
                    Selected = (DataCheckedField.Length > 0) ? (bool)DataBinder.GetPropertyValue(dataItem, DataCheckedField) : false
                };
                this.Items.Add(item);
            }
        }
    }
}
sshow
  • 8,820
  • 4
  • 51
  • 82
  • Looks interesting, but `dataSelectedField` shows error. Any suggestions? – MAW74656 Oct 13 '14 at 17:11
  • @MAW74656 Try replacing it with `dataCheckedField` instead. Looks like three year old typo. Please give feedback about your results! – sshow Oct 14 '14 at 01:42
  • 1
    This saved me over 6 years later. This was also very helpful in getting the custom tag to load in my project: https://stackoverflow.com/a/2009245/6297313 – BYUDigger Jan 25 '21 at 23:29
6

It's not possible using markup. What you can do is to bind the checkboxlist like you wanted it to work - with the bool in the DataValueField, and then simply add this as OnDataBound event.

protected void myCheckBoxList_DataBound(object sender, EventArgs e)
    {
        foreach (ListItem item in myCheckBoxList.Items)
        {
            item.Selected = bool.Parse(item.Value);
        }
    }

The difference between this solution and the one proposed by Jose Basilio is that this one works with all kind of databinding methods. For example binding with a SelectMethod using the new ModelBinding feature in v4.5.

Niklas Jonsson
  • 173
  • 2
  • 8
1

Using a DataList could be another option

<asp:DataList ID="dataListRoles" runat="server">
    <ItemTemplate>
        <asp:CheckBox runat="server" Text='<%# Eval("UserName ") %>' Checked='<%# Eval("IsInRole") %>' />
    </ItemTemplate>
</asp:DataList>
Homer
  • 7,594
  • 14
  • 69
  • 109
0

I would think you would have to tell the control what property to bind it to...in this case "InRole".

I played around with it and seems like there is noway to bind to the selection of the checkbox, you have to do it yourself. I was able to bind to the text and values of the checklist which only seem to deal with the label of each checkbox in the list.

CSharpAtl
  • 7,374
  • 8
  • 39
  • 53