How come checkedlistbox does not have datasource ? how to bind to a list of values?
Asked Answered
A

6

18

I am developing a Winform and I need a checkedlistbox. I have the values stored in an object which has a List property:

public static class Fields
{
    public static IList<string> FieldList { get; set; }

    static Fields()
    { ...//populate FieldList }
}

Now I would like my CheckedListBox to use Fields.FieldList as datasource. After searching online I found I needed to set

//in myForm_Load
mycheckedListBox.DataSource = Fields.FieldList;

But myCheckedListBox does not have a DataSource property.

Am I missing something here?

Aerugo answered 21/11, 2011 at 17:31 Comment(0)
P
17

Per the documentation, it should have this property... http://msdn.microsoft.com/en-us/library/system.windows.forms.checkedlistbox.datasource(VS.90).aspx

However, I also had the same issue on a project a while back, and used this CodeProject article to code the solution in the one project where I needed this feature.

Researching a bit more, I did find this:

http://connect.microsoft.com/VisualStudio/feedback/details/115199/checkedlistbox-datasource-displaymember-valuemember-are-hidden

Edit: The above link is no longer working, but the exceprt below is from the article that once resided there.

Posted by Microsoft on 5/30/2005 at 10:28 AM
Thanks for the feedback however this is by design. We do not support data binding on the CheckedListBox control. These properties are inherited from it base class and cannot be removed so we hid them form the property grid and IntelliSense.

That explains why the property exists, but doesn't show in Intellisense.

This blog post is worth a read as well: http://waxtadpole.wordpress.com/2009/10/12/assigning-custom-class-to-checkedlistbox-datasource/

Pudding answered 21/11, 2011 at 17:37 Comment(9)
Thanks. I had found the links you sent but since I also saw articles where people used this property, ... This is weird... Thanks anyways, at least I know someone else has had this problem.Aerugo
Ps: there is no documentation on how to use the item. I'm new to winform dev (just started today) so could you tell me how to make this item available in VS designer?...Aerugo
I dont think you can, unless you were to create your own class that overrides the CheckBoxList class. In more recent projects, I've just not used the control, and instead used a DataGridView in the rare cases that I really need to be able to check items individually. If your DataSource has a bit field, the DataGridView will automatically render it as a checkboxcolumn, and if not, I find it eassier to just add a DataColumn of type Boolean to get the same effect.Pudding
Nevermind, actually although the DataSource property doesn't show up in intellisence, it is actually there. So doing : checkedListBox1.DataSource = Fields.FieldList; actually works.Aerugo
Even though it will compile, you will get a runtime NullReferenceException when you try to set the DataSource.Holtz
FYI, the link to Microsoft Connect item is unavailable.Ietta
@Ietta - Thanks. I edited the answer, but the quote from the article is still relevant.Pudding
As above, you can do checkedListBox1.DataSource = .... and it will work, but it may throw an error in the debugger. If you hit continue, it will display properly.Airscrew
I can not verify the above dead links, but this clearly states that property exists even in 4.8 framework.Tibia
T
4

Here is how I am binding a List<T> of User objects into CheckedListBox.

((ListBox)myCheckedListBox).DataSource = listOfUsers;
((ListBox)myCheckedListBox).DisplayMember = "FullName";
((ListBox)myCheckedListBox).ValueMember = "UserID";

Of course this is not recommended, since documentation is telling us that this property is hidden.

The code above works, but I noticed some side effects in Visual Studio 2012 such as:

Delay for rendering checked marker:

After you click on the desired item, there is annoying delay to render the "checked" marker.

In my case, CheckOnClick property is True, CausesValidation is False.

Tuchman answered 19/2, 2014 at 17:46 Comment(1)
Well, I am sticking with the myCheckedListBox.Items.Add() by now, since the workaround above is acting wierd.Tuchman
H
3

This can be worked around by iterating through your would-be datasource and adding its items one-at-a-time. For example:

This, which will cause an exception:

myCheckedListBox.DataSource = myStringList;

Can be modified to this:

foreach (string myString in myStringList)
{
    myCheckedListBox.Items.Add(myString);
}
Holtz answered 4/9, 2013 at 22:49 Comment(0)
R
3

Personally I use a DataGridView that is bound to a DataTable that has a Boolean field along with a field for the display value.

If you hide the column headers and row headers then you get something pretty close to what a CheckedListBox gives you.

Regression answered 15/5, 2015 at 17:55 Comment(0)
A
2

I solved the problem by changing the ToString () method to the name that should appear:

public static class Fields
{
   public string MyDisplayMenber{ get; set; }

   public override string ToString(){
         return MyDisplayMenber;
   }
}

and turning into array list with objects:

{
  mycheckedlistbox.Items.AddRange(MyList.ToArray<Fields>());
}
Artificial answered 7/7, 2016 at 6:23 Comment(0)
I
1

I know this is pretty old; for the benefit of anyone who still has the same requirement, here's what worked for me. Note that I did not use DisplayMember or ValueMember properties, as it seems like it is discouraged (see @David Stratton's post above).

//References
// https://social.msdn.microsoft.com/Forums/vstudio/en-US/0e0da0c9-299e-46d0-b8b0-4ccdda15894c/how-to-assign-values-to-checkedlistbox-items-and-sum-these-values?forum=csharpgeneral


using Microsoft.Practices.EnterpriseLibrary.Data;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Windows.Forms;

namespace MyApp
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        DatabaseProviderFactory factory = new DatabaseProviderFactory(); 
        Database db = factory.Create("MyConnString");
        DataTable dt = db.ExecuteDataSet(CommandType.StoredProcedure, "ProcGetCustomers").Tables[0];
        var custlist = new List<CheckBoxItem<string, string>>();
        for (int i = 0; i < dt.Rows.Count; i++)
        {
            custlist.Add(Create(dt.Rows[i]["DESC"].ToString(), dt.Rows[i]["CODE"].ToString()));
        }
        checkedListBox1.Items.AddRange(custlist.Cast<object>().ToArray());


   }
    public class CheckBoxItem<K, V>
    {
        public CheckBoxItem(K displayValue, V hiddenValue)
        {
            DisplayValue = displayValue;
            HiddenValue = hiddenValue;
        }

        public K DisplayValue { get; private set; }
        public V HiddenValue { get; private set; }


        public override string ToString()
        {
            return DisplayValue == null ? "" : DisplayValue.ToString();
        }
    }
    public static CheckBoxItem<K, V> Create<K, V>(K displayValue, V hiddenValue)
    {
        return new CheckBoxItem<K, V>(displayValue, hiddenValue);
    }
  }
}
Ietta answered 7/11, 2014 at 19:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.