Почему в проверенном списке нет источника данных? как привязать к списку значений? - PullRequest
14 голосов
/ 21 ноября 2011

Я разрабатываю 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.

Я что-то здесь упускаю?

Ответы [ 6 ]

16 голосов
/ 21 ноября 2011

Согласно документации, оно должно иметь это свойство ... 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

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

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

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

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

4 голосов
/ 19 февраля 2014

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

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

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

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

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

После того, как вы щелкнете по нужному элементу, будет раздражающая задержка рендеринга «проверенного» маркера.

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

3 голосов
/ 15 мая 2015

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

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

3 голосов
/ 05 сентября 2013

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

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

myCheckedListBox.DataSource = myStringList;

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

foreach (string myString in myStringList)
{
    myCheckedListBox.Items.Add(myString);
}
1 голос
/ 07 ноября 2014

Я знаю, что это довольно старо; для тех, у кого все те же требования, вот что сработало для меня. Обратите внимание, что я не использовал свойства 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);
    }
  }
}
0 голосов
/ 07 июля 2016

Я решил проблему, изменив метод ToString () на имя, которое должно появиться:

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

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

и превратившись в список массивов с объектами:

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