我一直在努力解决这个问题,尽管我找不到解决方案。我为这篇长篇文章道歉,我试着简明扼要。
这是有用的:我创建了一个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的想法
答案 0 :(得分:1)
您需要设置ListBox的BindingContext
属性。
当ListBox (或任何控件)添加到表单上时,它会从表单继承其BindingContext
属性。现在,由于您将ListBox添加到另一个带有.BindingContext == null
的 TopLevel 控件,因此它不会从表单继承该属性,因此它没有BindingContext
。
您可以通过为ListBox创建新的BindingContext
来简单地避免此问题:
public void Source(DataTable dt, string display, string value)
{
this.suggestionDT = dt;
this.suggestionList.BindingContext = new BindingContext(); // <<<<<<<<<<<<<
this.suggestionList.DataSource = dt;
this.suggestionList.DisplayMember = display;
this.suggestionList.ValueMember = value;
}
您也可以从表单中复制BindingContext
而不是(通过CtlCombobox
控件或将其作为参数传递)。
希望有所帮助。