Click here to Skip to main content
15,867,488 members
Articles / Programming Languages / C#
Article

Bindable CheckedListBox

Rate me:
Please Sign up or sign in to vote.
4.85/5 (19 votes)
24 Jul 2006CPOL2 min read 260.3K   6.6K   56   32
In this article you will see how to bind a CheckedListBox to the data source and use features of multiple selection with data binding.

Sample Image - ExCheckedListBox1.jpg

Introduction

It seems that the .NET CheckedListBox even doesn't have primary binding facilities exists in the ListBox and ComboBox, because it must save multiple values in the database. Current article introducing an extended CheckedListBox that has a single property for setting and getting checked items, and also has binding facilities.

Problems

  • .NET CheckedListBox doesn't have binding facilities.
  • Because CheckedListBox works with an object collection it can't be bound to a data source.
  • CheckedListBox doesn't have a property representing whether item checked and it must be changed or getting data with Methods for one item or a collection of checked items hardly .

Needs

  • Creating a public bindable property that representing checked items and sets checked items based on it.
  • It must be one single property that when sets or gets it saves single primitive type value.
  • Items must be loaded from a data source (it could be lookup table) different from Value data source.
  • Because of list controls nature we must bind it to a column.

Using the code

A brief description of how to use the article or code. The class names, the methods and properties, any tricks or tips.

ExCheckedListBox

In the code samples major code belongs to ExCheckedListBox inherited from CheckedListBox of .NET framework.

It's extended CheckedListBox control and has three extra properties:

1. Value property:

This property is type of integer that brings ability to get and set checked item based on one single value. It works with bits in that integer, saves and retrieves values in single column.

C#
get
{
    ///Gets checked items in decimal mode from binary mode
    
    try
    {
        //each item in list has a number that is binary number in decimal mode
        //this number represents that number
        int poweredNumber = 1;
        //loop in all items of list
        for (int i = 0; i < this.Items.Count; i++)
        {
            //if item checked and the value doesn't contains poweredNumber 
            //then add poweredNumber to the value
            if((this.GetItemChecked(i)))
                this.value |= poweredNumber;
            //else if poweredNumber exists in the value remove from it
            else if ((this.value & poweredNumber) != 0)
                this.value -= poweredNumber;

            //raise to the power
            poweredNumber *= 2;
        }
    }
    catch (ArgumentException ex)
    {
        throw ex;
    }
    catch (Exception ex)
    {
        throw ex;
    }


    return this.value;
}
set
{
    ///sets checked items from binary mode converted from decimal value

    this.value = value;
    try
    {
        //each item in list has a number that is binary number in decimal mode
        //this number represents that number
        int poweredNumber = 1;
        //loop in all items of list
        for (int i = 0; i < this.Items.Count; i++)
        {
            //if poweredNumber exists in the value set checked on item
            if ((this.value & poweredNumber) != 0)
                this.SetItemCheckState(i, CheckState.Checked);
            //else remove checked from item
            else
                this.SetItemCheckState(i, CheckState.Unchecked);

            //raise to the power
            poweredNumber *= 2;
        }
    }
    catch (ArgumentException ex)
    {
        throw ex;
    }
    catch (Exception ex)
    {
        throw ex;
    }


}

2. DataSource property:

This property is type of object that brings ability to get and set data source like other collection controls (ListBox and ComboBox). In reality it's base DataSource property used, but it hided in the .NET CheckedListBox because of CheckedListBox logic. So I hide it by new keyword and reused base DataSource protected property.

C#
/// <summary>
/// Gets or sets the data source for this CustomControls.CheckedListBox.
/// Returns:
///    An object that implements the System.Collections.IList or 
//     System.ComponentModel.IListSource
///    interfaces, such as a System.Data.DataSet or an System.Array. The <BR>///    default is null.
///
///Exceptions:
///  System.ArgumentException:
///    The assigned value does not implement the System.Collections.IList or 
//     System.ComponentModel.IListSource
///    interfaces.
/// </summary>
[DefaultValue("")]
[AttributeProvider(typeof(IListSource))]
[RefreshProperties(RefreshProperties.All)]
[Browsable(true)]
public new object DataSource { 
    get 
    {
        return base.DataSource;
    }
    set 
    {
        base.DataSource = value;
        
    }
}

DataSource Property

3. DisplayMember property:

This property is type of string that brings ability to get and set data source specific column like other collection controls (ListBox and ComboBox).

In reality it's base DisplayMember property used, but it hided in the .NET CheckedListBox because of CheckedListBox logic.

So I hide it by new keyword and reused base DisplayMember protected property.

C#
/// <summary>
///   Gets or sets the property to display for this <BR>///   CustomControls.CheckedListBox.
///
/// Returns:
///     A System.String specifying the name of an object property that is <BR>///     contained in the collection specified by the <BR>///     CustomControls.CheckedListBox.DataSource property. The default is <BR>///     an empty string ("").
/// </summary>
[DefaultValue("")]
[TypeConverter("System.Windows.Forms.Design.DataMemberFieldConverter, <BR>System.Design, 
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
[Editor("System.Windows.Forms.Design.DataMemberFieldEditor, System.Design, 
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", 
typeof(UITypeEditor))]
[Browsable(true)]
public new string DisplayMember
{
    get
    {
        return base.DisplayMember;
    }
    set
    {
        base.DisplayMember = value;
        
    }
}

Demo Project

Demo project contains a SQL Script that creates two tables:

Products and Cities that have the same scenario of (presented products in specified cities).

Points of Interest

I wanted to implement another scenario (Questions and Answers) In that scenario we must navigate questions and answer the tests with multiple answers but there is a problem with data binding and this scenario.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Program Manager System Group
Iran (Islamic Republic of) Iran (Islamic Republic of)
Hossein Ghahvei Araghi
Birth date: 1978
Birth place: Iran
Academic Credentials : BS(Tehran University)
Microsoft Credentials : MCP, MCAD, MCTS 2.0, MCTS 3.5, MCPD 2.0, MCPD 3.5

Comments and Discussions

 
Questionhttp://www.codeproject.com/Articles/14916/Bindable-CheckedListBox#_comments Pin
mansoorttg28-May-12 5:01
mansoorttg28-May-12 5:01 
GeneralNew Simple Solution Pin
Alejandro Diaz8-May-08 11:20
Alejandro Diaz8-May-08 11:20 
QuestionRe: New Simple Solution Pin
José Filipe Néis5-Jun-08 8:13
José Filipe Néis5-Jun-08 8:13 
GeneralGreat Work Pin
UnRusoDeCaracas1-Apr-08 7:35
UnRusoDeCaracas1-Apr-08 7:35 
GeneralAcceptChanges bug Pin
richardw4828-Feb-08 2:16
richardw4828-Feb-08 2:16 
QuestionCheckListBox Pin
Member 234864126-Jan-08 16:21
Member 234864126-Jan-08 16:21 
GeneralCheckedListBox does have Datasource, DisplayMember properties. Pin
VB Prog18-Dec-07 9:57
VB Prog18-Dec-07 9:57 
GeneralRe: CheckedListBox does have Datasource, DisplayMember properties. Pin
AlejandroCBA7-Apr-08 11:43
AlejandroCBA7-Apr-08 11:43 
GeneralRe: CheckedListBox does have Datasource, DisplayMember properties. Pin
Seema Gosain17-Jan-11 21:23
Seema Gosain17-Jan-11 21:23 
GeneralVery nice, but... Pin
shaybar25-Oct-07 6:44
shaybar25-Oct-07 6:44 
QuestionRe: Very nice, but... Pin
richardw4828-Feb-08 2:18
richardw4828-Feb-08 2:18 
AnswerRe: Very nice, but... Pin
shaybar28-Feb-08 22:11
shaybar28-Feb-08 22:11 
GeneralRe: Very nice, but... Pin
shaybar28-Feb-08 22:16
shaybar28-Feb-08 22:16 
GeneralBindable CheckedListbox Pin
edgardepuy7-Aug-07 6:09
edgardepuy7-Aug-07 6:09 
Generalvery good Pin
abdelrahman khaled farooq22-Apr-07 8:42
abdelrahman khaled farooq22-Apr-07 8:42 
QuestionGet stuck in control??? Pin
xtempore11-Mar-07 22:27
xtempore11-Mar-07 22:27 
QuestionHow can i get the VALUE and DISPLAY MEMBER for the checked items? Pin
kylai224-Feb-07 22:42
kylai224-Feb-07 22:42 
QuestionWhy not use array or list as bound property? Pin
philippe dykmans30-Nov-06 4:26
philippe dykmans30-Nov-06 4:26 
AnswerRe: Why not use array or list as bound property? Pin
Hossein Ghahvei Araghi2-Dec-06 17:42
Hossein Ghahvei Araghi2-Dec-06 17:42 
GeneralRe: Why not use array or list as bound property? Pin
philippe dykmans16-Dec-06 3:26
philippe dykmans16-Dec-06 3:26 
GeneralVB.Net and additions Pin
Chris Kolkman10-Oct-06 6:10
Chris Kolkman10-Oct-06 6:10 
First of thanks for the great article - it really helped me to have a control I needed.

I've converted the code to VB (I used 2005 Express, but the code will probably work in previous versions, but I haven't tested that), and added a few properties.

I noticed you left out ValueMember, so I added that in as otherwise the SelectedValue property doesn't work.

I also added SelectedValues and CheckedValues to return arrays of the Selected/Checked values as determined by the ValueMember.

Imports System.ComponentModel
Imports System.Drawing.Design

Public Class ExCheckedListBox
    Inherits CheckedListBox

    Private _value As Integer

    Public Property Value() As Integer
        Get
            Try
                Dim poweredNumber As Integer = 1
                For i As Integer = 0 To Me.Items.Count - 1
                    If Me.GetItemChecked(i) Then
                        Me._value = Me._value Or poweredNumber
                    ElseIf Me._value And poweredNumber <> 0 Then
                        Me._value -= poweredNumber
                    End If
                    poweredNumber *= 2
                Next
            Catch ex1 As ArgumentException
                Throw ex1
            Catch ex As Exception
                Throw ex
            End Try
            Return Me._value
        End Get
        Set(ByVal value As Integer)
            Me._value = value
            Try
                Dim poweredNumber As Integer = 1
                For i As Integer = 0 To Me.Items.Count - 1
                    If Me._value And poweredNumber <> 0 Then
                        Me.SetItemCheckState(i, CheckState.Checked)
                    Else
                        Me.SetItemCheckState(i, CheckState.Unchecked)
                    End If
                    poweredNumber *= 2
                Next
            Catch ex1 As ArgumentException
                Throw ex1
            Catch ex As Exception
                Throw ex
            End Try
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets the data source for this CustomControls.CheckedListBox.
    ''' 
    ''' Exceptions:
    '''   System.ArgumentException:
    '''     The assigned value does not implement the System.Collections.IList or
    '''     System.ComponentModel.IListSource intefaces.
    ''' </summary>
    ''' <returns>
    ''' An object that implements the System.Collections.IList or
    ''' System.ComponentModel.IListSource interfaces, such as a 
    ''' System.Data.DataSet or an System.Array. The default is null.
    ''' </returns>
    <DefaultValue(""), AttributeProvider(GetType(IListSource)), RefreshProperties(RefreshProperties.All), Browsable(True)> _
    Public Shadows Property DataSource() As Object
        Get
            Return MyBase.DataSource
        End Get
        Set(ByVal value As Object)
            MyBase.DataSource = value
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets the property to display for this
    ''' CustomControls.CheckedListBox
    ''' </summary>
    ''' <returns>
    ''' A System.String specifying the name of the object property that is
    ''' contained in the collection specified by the
    ''' CustomControls.CheckedListBox.DataSource property. The default is
    ''' an empty string ("").
    ''' </returns>
    <DefaultValue(""), _
     TypeConverter("System.Windows.Forms.Design.DataMemberFieldConverter, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"), _
     Editor("System.Windows.Forms.Design.DataMemberFieldEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", GetType(UITypeEditor)), _
     Browsable(True)> _
    Public Shadows Property DisplayMember() As String
        Get
            Return MyBase.DisplayMember
        End Get
        Set(ByVal value As String)
            MyBase.DisplayMember = value
        End Set
    End Property

    <DefaultValue(""), _
     TypeConverter("System.Windows.Forms.Design.DataMemberFieldConverter, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"), _
     Editor("System.Windows.Forms.Design.DataMemberFieldEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", GetType(UITypeEditor)), _
     Browsable(True)> _
    Public Shadows Property ValueMember() As String
        Get
            Return MyBase.ValueMember
        End Get
        Set(ByVal value As String)
            MyBase.ValueMember = value
        End Set
    End Property

    <Browsable(False)> _
    Public ReadOnly Property SelectedValues() As Array
        Get
            Dim i As Integer = -1
            Dim ret() As Object = Nothing
            For Each idx As Integer In Me.SelectedIndices
                i += 1
                ReDim Preserve ret(i)
                ret(i) = CType(MyBase.DataManager.List.Item(idx), DataRowView).Item(Me.ValueMember)
            Next
            Return ret
        End Get
    End Property

    <Browsable(False)> _
    Public ReadOnly Property CheckedValues() As Array
        Get
            Dim i As Integer = -1
            Dim ret() As Object = Nothing
            For Each idx As Integer In Me.CheckedIndices
                i += 1
                ReDim Preserve ret(i)
                ret(i) = CType(MyBase.DataManager.List.Item(idx), DataRowView).Item(Me.ValueMember)
            Next
            Return ret
        End Get
    End Property

End Class


Thanks again!
GeneralRe: VB.Net and additions Pin
Karl Rhodes6-Mar-07 0:35
Karl Rhodes6-Mar-07 0:35 
GeneralRe: VB.Net and additions Pin
karenpayne24-Sep-09 3:46
karenpayne24-Sep-09 3:46 
Questionhow can i get the text of selected item Pin
Amar Chaudhary30-Sep-06 13:29
Amar Chaudhary30-Sep-06 13:29 
AnswerRe: how can i get the text of selected item [modified] Pin
K. Zimny29-Nov-06 8:01
K. Zimny29-Nov-06 8:01 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.