Anton
Anton

Reputation: 33

How can I change ComboBox's drop down list dynamically, when it's showed on-screen already?

I populate combo box with items from list TownList, filtered by text searchString in combobox

List<Towns> towns = PIKBLL.TownList.FindAll(p => p.Name.Contains(searchString)); (sender as ComboBox).DataSource = towns;

And I do it every time user enters text in combo.

Also, in same event handler I tell combobox to show it's drop down this way: cb.DroppedDown = true; Everything works fine, but...when filter results count gets smaller and smaller, combobox's drop-down height remains the same.

I've tried to call such methods as:

cb.PerformLayout();
cb.Refresh();
cb.Update();

I've tried this as well:

if (towns.Count != 0)
{
    if (towns.Count * cb.ItemHeight < 300)
        cb.DropDownHeight = towns.Count * cb.ItemHeight;
     else
        cb.DropDownHeight = cb.ItemHeight * 15;
 }

My question is: how can I tell combobox to recalculate it's list of items and redraw it dynamically without just hiding and showing this list again?

Upvotes: 0

Views: 2903

Answers (3)

King King
King King

Reputation: 63327

If you want to see the code, I'll post the best of it here, not complete but can help you get started:

    [DllImport("user32")]
    private static extern int GetComboBoxInfo(IntPtr hwnd, out COMBOBOXINFO comboInfo);                
    [DllImport("user32")]
    private static extern int GetWindowRect(IntPtr hwnd, out RECT rect);
    [DllImport("user32")]
    private static extern int MoveWindow(IntPtr hwnd, int x, int y, int width, int height);
    struct RECT
    {
        public int left, top, right, bottom;
    }
    struct COMBOBOXINFO
    {
        public int cbSize;
        public RECT rcItem;
        public RECT rcButton;
        public int stateButton;
        public IntPtr hwndCombo;
        public IntPtr hwndItem;
        public IntPtr hwndList;//This is the Handle of the drop-down list, the one we care here.
    }
    COMBOBOXINFO comboInfo = new COMBOBOXINFO();
    comboInfo.cbSize = Marshal.SizeOf(comboInfo);//Set the size needed to hold the data of the drop-down list Handle
    GetComboBoxInfo(comboBox.Handle, out comboInfo);//Get the Handle of the drop-down list of the combobox and pass out to comboInfo
    //You use the MoveWindow() function to change the position and size of a window via its Handle.
    //show the drop-down list
    comboBox.DroppedDown = true;
    //You use the GetWindowRect() to get the RECT of a window via its Handle
    //this method just sets the new Width for a window
    private void SetWidth(IntPtr hwnd, int newWidth){
       RECT rect;
       GetWindowRect(hwnd, out rect);
       MoveWindow(hwnd, rect.left, rect.top, newWidth, rect.bottom-rect.top);
    }
    //Test on a drop-down list of a combobox
    SetWidth(comboInfo.hwndList, 400);
    //....
    //Your problem is change the Height not the Width of the drop-down list of a combobox
    //You have to notice that when the drop-down list is really dropped down, you will have to set new Height for the drop-down list only. However if it is popped-up, you will have to set new Height and calculate the new `Top` of the drop-down list to move the drop-down list accordingly. I've tested successfully.

Upvotes: 1

Guilherme H. J.
Guilherme H. J.

Reputation: 89

You want an opened ComboBox to be updated while a user type its searchString. Have you considered the use of an AutocompleteBox? It will do the same.

Upvotes: 0

Romano Zumb&#233;
Romano Zumb&#233;

Reputation: 8079

I think there is no way to force a normal ComboBox into this behavior. You will have to create your own ComboBox that implements it. A good starting point will be this article:

ComboBox List Control Host

Upvotes: 0

Related Questions