Я весь день боролся с этой проблемой, хотя не мог найти решение. Я прошу прощения за длинный пост, я старался быть кратким и ясным.
Вот что работает : я создаю Form
и внутри его класса я динамически создаю ListBox
и устанавливаю DataSource
в DataTable
следующим образом:
public partial class FrmAddress : Form
{
private ListBox listBox1 = new ListBox();
public FrmAddress()
{
this.InitializeComponent();
[...]
this.Controls.Add(listBox1);
}
[...]
private void Load_Countries()
{
this.listBox1.DataSource = dtCountries;
this.listBox1.DisplayMember = "Country";
this.listBox1.ValueMember = "Country_ID";
}
[...]
}
Это не работает : создание пользовательского элемента управления (унаследованного от ToolStripDown
), создание нового экземпляра ToolStripControlHost(listBox1)
, добавление этого экземпляра в ToolStripDown
. Установите listBox1.DataSource
на DataTable
. Когда отображается ToolStripDown
, список есть, но пустой (без отображения содержимого источника данных).
public class CtlDropdownPopup : ToolStripDropDown
{
ListBox controlToPop;
ToolStripControlHost controlHost;
public CtlDropdownPopup(ListBox controlToPop)
{
this.controlToPop = controlToPop;
this.controlToPop.Location = Point.Empty;
this.controlHost = new ToolStripControlHost(this.controlToPop);
[...]
this.Items.Add(this.controlHost);
}
}
public class CtlCombobox : ComboBox
{
private readonly CtlDropdownPopup suggestionDropDown;
private readonly ListBox suggestionList = new ListBox();
public CtlCombobox()
{
this.suggestionDropDown = new CtlDropdownPopup(this.suggestionList);
}
public void Source(DataTable dt, string display, string value)
{
this.suggestionDT = dt;
this.suggestionList.DataSource = dt;
this.suggestionList.DisplayMember = display;
this.suggestionList.ValueMember = value;
}
}
Пользовательский CtlDropdownPopup
называется как: (упрощенно)
private CtlCombobox LstCountry;
this.LstCountry.Source(dtCountries, "Country", "Country_ID");
Как я уже сказал, ToolStripDropDown
отображается с listBox1
в нем, но список пуст. Любопытно, если я изменю метод Source()
на
public void Source(DataTable dt, string display, string value)
{
this.suggestionDT = dt;
// this.suggestionList.DataSource = dt;
// this.suggestionList.DisplayMember = display;
// this.suggestionList.ValueMember = value;
if (this.suggestionList != null)
{
foreach (DataRow row in dt.Rows)
{
this.suggestionList.Items.Add(row[display].ToString());
}
}
}
Список отображается с элементами на нем. Хотя этот обходной путь делает свою работу, раздражает не то, что я не могу найти ответ, почему я не могу установить DataSource
напрямую (как я это сделал в первом примере), но вручную добавление элементов.
Любые идеи действительно помогут мне хорошо выспаться сегодня вечером:)
Мысль № 1: Я полагаю, поскольку тот же самый dtCountries
связан с другим ComboBox1.DataSource
, это может быть проблемой, поэтому я установил this.controlToPop.DataSource = dt.Copy();
в надежде "это не каким-то образом связано с выпадающий список ", но проблема остается.
Примечание : Я пытаюсь создать пользовательский комбинированный список, который предлагает элементы в пределах DataTable
.
Идея от https://www.codeproject.com/Tips/789705/Create-combobox-with-search-and-suggest-list