当我们在屏幕上显示时,如何动态地改变ComboBox的下拉列表? [英] How can I change ComboBox's drop down list dynamically, when it's showed on-screen already?

查看:596
本文介绍了当我们在屏幕上显示时,如何动态地改变ComboBox的下拉列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用组合框中的文本 searchString 填充列表中的项目 TownList b
$ b

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



每当用户在combo中输入文本时,



此外,在同一个事件处理程序中,我告诉组合框显示它以这种方式下拉: cb.DroppedDown = true; 一切正常,但是...当过滤器结果计数变得越来越小时,组合框的下拉高度保持不变。



我试图调用这样的方法as:

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

我也尝试过:

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

我的问题是:如何告诉combobox重新计算它的项目列表,重新绘制它动态,而不是隐藏和再次显示此列表?

解决方案

如果你想看到代码,我会在这里发布最好的,不完整,但可以帮助你开始:

  [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; //这是下拉列表的句柄,我们在这里关心的。
}
COMBOBOXINFO comboInfo = new COMBOBOXINFO();
comboInfo.cbSize = Marshal.SizeOf(comboInfo); //设置保存下拉列表数据所需的大小Handle
GetComboBoxInfo(comboBox.Handle,out comboInfo); //获取组合框下拉列表的句柄并传递到comboInfo
//使用MoveWindow()函数通过其Handle来更改窗口的位置和大小。
//显示下拉列表
comboBox.DroppedDown = true;
//使用GetWindowRect()通过它的Handle获取窗口的RECT
//这个方法只为窗口设置新的宽度
private void SetWidth(IntPtr hwnd,int newWidth){
RECT rect;
GetWindowRect(hwnd,out rect);
MoveWindow(hwnd,rect.left,rect.top,newWidth,rect.bottom-rect.top);
}
//在组合框的下拉列表中测试
SetWidth(comboInfo.hwndList,400);
// ....
//您的问题是更改组合框下拉列表的高度不是宽度
//您必须注意,当下拉列表列表确实被删除,您将不得不为下拉列表设置新的高度。但是,如果弹出,您将必须设置新的高度,并计算下拉列表的新的顶部,以相应地移动下拉列表。我已经测试成功。


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?

解决方案

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.

这篇关于当我们在屏幕上显示时,如何动态地改变ComboBox的下拉列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆