Как получилось, что 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.
Я что-то пропустил?
Ответы
Ответ 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>());
}