1

尽管我找不到解决方案,但我整天都在为这个问题苦苦挣扎。我为这篇冗长的帖子道歉,我试图简洁明了。

这是有效的:我创建一个Form并在其类中ListBox动态创建一个并将其设置DataSourceDataTable如下:

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.DataSourceDataTable。显示时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与 other 相关联ComboBox1.DataSource,这可能是问题所在,所以我this.controlToPop.DataSource = dt.Copy();希望“它与组合框没有某种联系”,但问题仍然存在。

旁注:我正在尝试创建一个自定义组合框,它建议DataTable.

来自https://www.codeproject.com/Tips/789705/Create-combobox-with-search-and-suggest-list的想法

4

1 回答 1

2

您需要设置BindingContextListBox 的属性。

将 ListBox (或任何控件)添加到窗体时,它会BindingContext从窗体继承其属性。现在,由于您使用 将 ListBox 添加到另一个TopLevel控件.BindingContext == null,因此它不会从表单继承该属性,因此它没有BindingContext.

BindingContext您可以通过为 ListBox创建一个新的来简单地避免此问题:

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控件或将其作为参数传递)

希望有帮助。

于 2018-05-13T06:46:10.450 回答