Подтвердить что ты не робот

Как получилось, что checklistbox не имеет источника данных? как привязываться к списку значений?

Я разрабатываю Winform, и мне нужен checklistbox. У меня есть значения, хранящиеся в объекте со свойством 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.

Я что-то пропустил?

4b9b3361

Ответ 1

В документации должно быть это свойство... http://msdn.microsoft.com/en-us/library/system.windows.forms.checkedlistbox.datasource(VS.90).aspx

Однако у меня также была такая же проблема в проекте, и я использовал эту статью CodeProject для кодирования решения в одном проекте где мне нужна эта функция.

Исследование немного больше, я нашел это:

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

Изменить: выше ссылка больше не работает, но exceprt ниже из статьи, которая когда-то там жила.

Отправлено Microsoft на 5/30/2005 в 10:28
Спасибо за ответ однако это по дизайну. Мы не поддерживаем привязку данных к Контроль CheckedListBox. Эти свойства унаследованы от него класса и не могут быть удалены, поэтому мы спрятали их в сетке свойств и IntelliSense.

Это объясняет, почему свойство существует, но не показано в Intellisense.

Это сообщение в блоге тоже стоит прочитать: http://waxtadpole.wordpress.com/2009/10/12/assigning-custom-class-to-checkedlistbox-datasource/

Ответ 2

Вот как я привязываю List<T> объектов User к CheckedListBox.

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

Конечно это не рекомендуется, так как документация сообщает нам, что это свойство скрыто.

Приведенный выше код работает, но я заметил некоторые побочные эффекты в Visual Studio 2012, такие как:

Задержка для рендеринга отмеченного маркера:

После того, как вы нажмете на нужный элемент, есть раздражающая задержка, чтобы отобразить маркер "checked".

В моем случае свойство CheckOnClick имеет значение True, CausesValidation - False.

Ответ 3

Это можно обойти, итерации через ваш потенциальный источник данных и добавление его элементов по одному. Например:

Это приведет к возникновению исключения:

myCheckedListBox.DataSource = myStringList;

Можно изменить на это:

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

Ответ 4

Лично я использую DataGridView, связанный с DataTable, который имеет логическое поле вместе с полем для отображаемого значения.

Если вы спрячете заголовки столбцов и заголовки строк, вы получите что-то очень близкое к тому, что дает вам CheckedListBox.

Ответ 5

Я знаю, что это довольно старый; на благо тех, кто все еще имеет такое же требование, вот что сработало для меня. Обратите внимание, что я не использовал свойства DisplayMember или ValueMember, так как кажется, что он обескуражен (см. Сообщение @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>());
}