zoukankan      html  css  js  c++  java
  • 自定义下拉列表控件

    1. 问题及需求
    • 输入汉字或全拼或简拼均可得到结果(此需求用原生的ComboBox不容易实现)
    • 点击文本框时弹出下拉列表
    • 进入文本框时弹出下拉列表
    • 输入文字时,如果有结果,则弹出下拉列表
    • 除文本框和下拉列表外,点击任何地方均隐藏下拉列表
    • 单击下拉列表中的文字,文本出现在文本框,关闭下拉列表
    • 下拉列表出现后,默认选中第一项,第一项高亮
    • 回车后下拉列表中选中的文本出现在文本框中

    2.解决思路

    • 用Panel作为容器,装载ListView,作为下拉列表的数据容器
    • 定义下拉列表显示方法,并使用+=将其添加到文本框的Enter和Click事件后
    • 使用DataTable的Select方法过滤数据,并将其赋值给ListView的DataSource
    • 使用windows消息机制过滤消息,获得鼠标所在位置的控件,判断是否文本框和ListView控件,如果是,不处理,如果不是,则隐藏下拉列表
    • 文本框中回车时,取ListView选中的项的值,并赋给文本框
    3.代码
     
    以下是核心代码:
     
    使控件所在form继承IMessageFilter,并实现bool PreFilterMessage(ref Message m)方法
            
    public bool PreFilterMessage(ref System.Windows.Forms.Message message)
            {
                int hwnd = 0;
                StringBuilder winText = new StringBuilder();
                StringBuilder clsName = new StringBuilder();
                StringBuilder pText = new StringBuilder();
     
    //获取鼠标所在位置获取窗体或控件的信息,包括Handle,窗体(控件)的标题,窗体(控件)的类名,父容器的标题
                APImouse.GetWindowFromPoint(ref hwnd, ref winText, ref clsName, ref pText);
     
                // 鼠标左键消息
                if (message.Msg >= 513 && message.Msg <= 515)
                {
                    if (hwnd != (int)listBox1.Handle && hwnd != (int)tbBrand.Handle)
                        pnlBrandList.Visible = false;
                }
     
                return false;
            }
     
     
    public struct POINT
        {
            public int x;
            public int y;
        }
     
        public class APImouse
        {
            [DllImport("user32.dll", EntryPoint = "GetCursorPos")]
            public static extern int GetCursorPos(ref POINT lpPoint);
            [DllImport("user32.dll", EntryPoint = "WindowFromPoint")]//指定坐标处窗体句柄
            public static extern int WindowFromPoint(int xPoint, int yPoint);
            [DllImport("user32.dll", EntryPoint = "GetWindowText")]//指定坐标处窗体标题
            public static extern int GetWindowText(int hwnd, string lpString, int cch);
     
            [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
            static extern int GetClassName(int hWnd, StringBuilder lpClassName, int nMaxCount);
            [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
            static extern int GetParent(int hWnd);
     
     
            public static void GetWindowFromPoint(ref int hwnd, ref StringBuilder winText, ref StringBuilder clsName, ref StringBuilder pText)
            {
     
                int parentHandle = 0;
                int maxLen = 128;
     
                POINT pnt = new POINT();
     
                parentHandle = GetCursorPos(ref pnt);
     
                hwnd = WindowFromPoint(pnt.x, pnt.y);
     
                winText = new StringBuilder(maxLen);
     
                parentHandle = GetWindowText(hwnd, winText.ToString(), maxLen);
     
                clsName = new StringBuilder(maxLen);
     
                parentHandle = GetClassName(hwnd, clsName, maxLen);
     
                pText = new StringBuilder(maxLen);
     
                parentHandle = GetParent(hwnd);
     
                parentHandle = GetWindowText(parentHandle, pText.ToString(), maxLen);
            }
        }
    

      

  • 相关阅读:
    gethostname()和gethostbyname()获取IP地址和计算机名
    struct hostent结构体
    Memcached在Windows 中启动
    Mysql5.7免安装版跳坑测试
    Memcached 开源,支持高性能,高并发以及分布式的内存缓存软件
    关于压力测试使用的工具
    分布式实时同步系统
    oracle 遍历生成树的节点层次号
    支付宝的及时到账接口
    Kubernetes和TensorFlow集群搭建
  • 原文地址:https://www.cnblogs.com/Sabre/p/3854811.html
Copyright © 2011-2022 走看看