【问题标题】:How come checkedlistbox does not have datasource ? how to bind to a list of values?为什么checkedlistbox没有数据源?如何绑定到值列表?
【发布时间】:2011-11-21 17:31:12
【问题描述】:

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

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

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

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

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

但 myCheckedListBox 没有 DataSource 属性。

我错过了什么吗?

【问题讨论】:

    标签: c# winforms checkedlistbox


    【解决方案1】:

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

    但是,不久前我在一个项目中也遇到了同样的问题,并使用this CodeProject article 在我需要此功能的一个项目中编写解决方案。

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

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

    编辑:上面的链接不再有效,但下面的摘录来自曾经在那里的文章。

    由 Microsoft 于 2005 年 5 月 30 日上午 10:28 发布
    感谢您的反馈 然而,这是设计使然。我们不支持在 CheckedListBox 控件。这些属性继承自它的基 类并且不能被删除,所以我们将它们隐藏在属性网格中 智能感知。

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

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

    【讨论】:

    • 谢谢。我找到了您发送的链接,但是由于我还看到了人们使用此属性的文章,...这很奇怪...无论如何,谢谢,至少我知道其他人遇到了这个问题。
    • Ps:没有关于如何使用该项目的文档。我是 winform dev 的新手(今天才开始)所以你能告诉我如何在 VS 设计器中使用这个项目吗?...
    • 我不认为你可以,除非你要创建自己的类来覆盖 CheckBoxList 类。在最近的项目中,我只是没有使用控件,而是在极少数情况下使用 DataGridView,我确实需要能够单独检查项目。如果您的 DataSource 有一个位字段,DataGridView 将自动将其呈现为一个复选框列,如果没有,我发现添加一个布尔类型的 DataColumn 以获得相同的效果更容易。
    • 即使它会编译,当你尝试设置 DataSource 时,你会得到一个运行时 NullReferenceException。
    • @FMFF - 谢谢。我编辑了答案,但文章中的引用仍然相关。
    【解决方案2】:

    以下是我将User 对象中的List&lt;T&gt; 绑定到CheckedListBox 中的方法。

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

    当然不推荐这样做,因为文档告诉我们这个属性是隐藏的。

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

    延迟渲染选中标记:

    点击所需的项目后,渲染“选中”标记会出现烦人的延迟。

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

    【讨论】:

    • 好吧,我现在坚持使用myCheckedListBox.Items.Add(),因为上面的解决方法很奇怪。
    【解决方案3】:

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

    如果你隐藏列标题和行标题,那么你得到的东西非常接近 CheckedListBox 给你的东西。

    【讨论】:

      【解决方案4】:

      这可以通过遍历您的潜在数据源并一次添加其项目来解决。例如:

      这个,会导致异常:

      myCheckedListBox.DataSource = myStringList;
      

      可以修改成这样:

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

      【讨论】:

        【解决方案5】:

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

        //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);
            }
          }
        }
        

        【讨论】:

          【解决方案6】:

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

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

          并变成带有对象的数组列表:

          {
            mycheckedlistbox.Items.AddRange(MyList.ToArray<Fields>());
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-02-18
            • 1970-01-01
            • 2013-02-15
            • 2013-02-13
            • 1970-01-01
            • 1970-01-01
            • 2012-09-16
            相关资源
            最近更新 更多