Reputation: 33
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
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
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
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:
Upvotes: 0