为什么checkedlistbox没有数据源? 如何绑定到值列表?

我正在开发一个Winform,我需要一个checkedlistbox。 我将值存储在具有List属性的对象中:

public static class Fields { public static IList FieldList { get; set; } static Fields() { ...//populate FieldList } } 

现在我希望我的CheckedListBox使用Fields.FieldList作为数据源。 在线搜索后,我发现我需要设置

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

但myCheckedListBox没有DataSource属性。

我在这里错过了什么吗?

根据文档,它应具有此属性… http://msdn.microsoft.com/en-us/library/system.windows.forms.checkedlistbox.datasource(VS.90).aspx

但是,我在前一个项目中也遇到了同样的问题,并使用这个CodeProject文章来编写我需要此function的项目中的解决方案。

研究了一下,我确实找到了这个:

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

编辑:以上链接不再有效,但下面的例外情况来自曾经居住过的文章。

由Microsoft于2005年5月30日上午10:28发布
感谢您的反馈,但这是设计的。 我们不支持CheckedListBox控件上的数据绑定。 这些属性inheritance自它的基类,无法删除,因此我们将它们隐藏在属性网格和IntelliSense中。

这解释了为什么属性存在,但在Intellisense中没有显示。

这篇博文也值得一读: http : //waxtadpole.wordpress.com/2009/10/12/assigning-custom-class-to-checkedlistbox-datasource/

这是我如何将ListUser对象绑定到CheckedListBox。

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

当然不建议这样做 ,因为文档告诉我们隐藏了这个属性。

上面的代码有效,但我注意到Visual Studio 2012中的一些副作用,例如:

渲染已检查标记的延迟:

单击所需的项目后,呈现“已检查”标记会有恼人的延迟。

在我的例子中, CheckOnClick属性为True, CausesValidation为False。

我个人使用绑定到DataTableDataGridView ,该DataTable具有布尔字段以及显示值的字段。

如果您隐藏列标题和行标题,那么您将获得与CheckedListBox提供的内容非常接近的内容。

这可以通过迭代您的可能数据源并一次添加其项目来解决。 例如:

这会导致exception:

 myCheckedListBox.DataSource = myStringList; 

可以修改为:

 foreach (string myString in myStringList) { myCheckedListBox.Items.Add(myString); } 

我知道这很老了; 为了任何仍然有相同要求的人的利益,这对我有用。 请注意,我没有使用DisplayMemberValueMember属性,因为它似乎不鼓励(请参阅上面的@David Stratton的post)。

 //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>(); 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().ToArray()); } public class CheckBoxItem { 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 Create(K displayValue, V hiddenValue) { return new CheckBoxItem(displayValue, hiddenValue); } } } 

我通过将ToString()方法更改为应该出现的名称来解决问题:

 public static class Fields { public string MyDisplayMenber{ get; set; } public override string ToString(){ return MyDisplayMenber; } } 

并转换为带有对象的数组列表:

 { mycheckedlistbox.Items.AddRange(MyList.ToArray()); }