2

I use a ToolStripControlHost to wrap a ListBox control for adding it into a ToolStripDropDown, but found items I assign to ListBox.DataSource not shown up, and ComboBox.DataSource not work as well, I don't understand why ListContorl.DataSource not function in ToolStripControlHost.

        ListBox listBox = new ListBox();
        listBox.DataSource = new string[] { "1", "2", "3" };

        ToolStripControlHost host = new ToolStripControlHost(listBox)
        {
            Margin = Padding.Empty,
            Padding = Padding.Empty,
            AutoSize = false
        };

        ToolStripDropDown dropDown = new ToolStripDropDown() { AutoClose = false };
        dropDown.Items.Add(host);
        dropDown.Show();

Edit

I found the problem is ToolStripDropDown has not parents to provide BindingContext, so it will happen to any control with DataManager.

Cason
  • 95
  • 1
  • 9

2 Answers2

1

Good question. Seems like the ListBox has to be added to a top level control (such as a Form) in order to force it to use the DataSource property. E.g. Add this code after the DataSource is assigned:

public class DataForm : Form {

    ToolStripDropDown dropDown = new ToolStripDropDown() { AutoClose = true };
    ListBox listBox = new ListBox();
    public DataForm() {
        listBox.DataSource = new string[] { "1", "2", "3" };
        var hWnd = listBox.Handle; // required to force handle creation
        using (var f = new Form()) {
            f.Controls.Add(listBox);
            f.Controls.Remove(listBox);
        }

        ToolStripControlHost host = new ToolStripControlHost(listBox) {
            Margin = Padding.Empty,
            Padding = Padding.Empty,
            AutoSize = false
        };

        dropDown.Items.Add(host);
    }

    protected override void OnMouseClick(MouseEventArgs e) {
        base.OnMouseClick(e);
        dropDown.Show(Cursor.Position);
    }
}

You could also look at the ListBox.cs source code to try and figure out underlying cause: http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/ListBox.cs,03c7f20ed985c1fc

Loathing
  • 5,109
  • 3
  • 24
  • 35
  • Hi Loathing, thank you for your help! I can't make it work by add this code after the DataSource is assigned, could you give me a hint which line should I start with ListBox.cs? – Cason Oct 06 '15 at 04:46
  • @Cason Sorry, I forgot to include an important line, which is: `var hWnd = listBox.Handle;` which seems like it does nothing, but actually accessing the `Handle` property causes the `Handle` to be created. The full code is posted. – Loathing Oct 06 '15 at 05:16
0

I found the problem is ToolStripDropDown has no parents to provide a BindingContext, so the solution is assign the BindingContext of the Form.

        ListBox listBox = new ListBox();
        listBox.DataSource = new string[] { "1", "2", "3" };
        listBox.BindingContext = this.BindingContext; //assign a BindingContext

        ToolStripControlHost host = new ToolStripControlHost(listBox)
        {
            Margin = Padding.Empty,
            Padding = Padding.Empty,
            AutoSize = false
        };

        ToolStripDropDown dropDown = new ToolStripDropDown() { AutoClose = false };
        dropDown.Items.Add(host);
        dropDown.Show();
Cason
  • 95
  • 1
  • 9