防止 System.Window.Forms.ComboBox 的自动选择行为 (C#)

2024-03-05

背景:

我有一个Forms.ComboBox with a DropDownStyle = DropDown.

我不使用AutoComplete,但我实现了类似的东西,它不仅过滤文本的开头,而且使用正则表达式并显示与输入的文本匹配的所有项目。这很好用。

但是,当我键入匹配项的第一个字母时,ComboBox回到原来的行为并设置DroppedDown = true并自动选择第一个条目并完成文本以匹配所选项目(类似于AutoCompleteMode附加)。我想要的是没有自动选择和自动完成。

到目前为止我发现的是,我必须以某种方式阻止SendMessage() with CB_FINDSTRING被召唤和替换CB_FINDSTRING with CB_FINDSTRINGEXACT (MSDN 链接 http://msdn.microsoft.com/en-us/library/windows/desktop/bb775837(v=vs.85).aspx).

我想我必须扩展 ComboBox 类,但我不确定必须重写哪些方法。我正在使用 C# .NET Framework v3.5。

问题:

  • 我如何延长Windows.Forms.ComboBox防止自动选择行为?

Links:

如何防止下拉组合框中的自动选择(精确匹配除外)? https://stackoverflow.com/questions/16544663/how-can-i-prevent-auto-select-in-combobox-on-drop-down-except-for-exact-matches(没有帮助我)


尝试这个:

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows.Forms;

using Opulos.Core.Win32;

namespace Opulos.Core.UI {

// Extension class to disable the auto-select behavior when a combobox is in DropDown mode.
public static class ComboBoxAutoSelectEx {

    public static void AutoSelectOff(this ComboBox combo) {
        Data.Register(combo);
    }

    public static void AutoSelectOn(this ComboBox combo) {
        Data data = null;
        if (Data.dict.TryGetValue(combo, out data)) {
            data.Dispose();
            Data.dict.Remove(combo);
        }
    }

    private class Data {
        // keep a reference to the native windows so they don't get disposed
        internal static Dictionary<ComboBox, Data> dict = new Dictionary<ComboBox, Data>();

        // a ComboBox consists of 3 windows (combobox handle, text edit handle and dropdown list handle)
        ComboBox combo;
        NW nwList = null; // handle to the combobox's dropdown list
        NW2 nwEdit = null; // handle to the edit window

        internal void Dispose() {
            dict.Remove(this.combo);
            this.nwList.ReleaseHandle();
            this.nwEdit.ReleaseHandle();
        }

        public static void Register(ComboBox combo) {
            if (dict.ContainsKey(combo))
                return; // already registered

            Data data = new Data() { combo = combo };
            Action assign = () => {
                if (dict.ContainsKey(combo))
                    return; // already assigned

                COMBOBOXINFO info = COMBOBOXINFO.GetInfo(combo); // new COMBOBOXINFO();
                //info.cbSize = Marshal.SizeOf(info);
                //COMBOBOXINFO2.SendMessageCb(combo.Handle, 0x164, IntPtr.Zero, out info);

                dict[combo] = data;
                data.nwList = new NW(combo, info.hwndList);
                data.nwEdit = new NW2(info.hwndEdit);
            };

            if (!combo.IsHandleCreated)
                combo.HandleCreated += delegate { assign(); };
            else
                assign();

            combo.HandleDestroyed += delegate {
                data.Dispose();
            };
        }
    }

    private class NW : NativeWindow {
        ComboBox combo;
        public NW(ComboBox combo, IntPtr handle) {
            this.combo = combo;
            AssignHandle(handle);
        }

        private const int LB_FINDSTRING = 0x018F;
        private const int LB_FINDSTRINGEXACT = 0x01A2;

        protected override void WndProc(ref Message m) {
            if (m.Msg == LB_FINDSTRING) {
                m.Msg = LB_FINDSTRINGEXACT;
            }

            base.WndProc(ref m);

            if (m.Msg == LB_FINDSTRINGEXACT) {
                String find = Marshal.PtrToStringAuto(m.LParam);
                for (int i = 0; i < combo.Items.Count; i++) {
                    Object item = combo.Items[i];
                    if (item.Equals(find)) {
                        m.Result = new IntPtr(i);
                        break;
                    }
                }
            }
        }
    }

    private class NW2 : NativeWindow {
        public NW2(IntPtr handle) {
            AssignHandle(handle);
        }

        private const int EM_SETSEL = 0x00B1;
        private const int EM_GETSEL = 0x00B0;

        protected override void WndProc(ref Message m) {
            if (m.Msg == EM_SETSEL) {
                // if this code is not here, then the entire combobox text is selected
                // which looks ugly, especially when there are multiple combo boxes.
                //
                // if this method returns immediately, then the caret position is set
                // to (0, 0). However, it seems that calling EM_GETSEL has a side effect
                // that the caret position is mostly maintained. Sometimes it slips back
                // to (0, 0).
                SendMessage(Handle, EM_GETSEL, IntPtr.Zero, IntPtr.Zero);
                //int selStart = (sel & 0x00ff);
                //int selEnd = (sel >> 16) & 0x00ff;
                //Debug.WriteLine("EM_GETSEL: " + selStart + " nEnd: " + selEnd);
                return;
            }
            base.WndProc(ref m);
        }

        [DllImportAttribute("user32.dll", SetLastError=true)]
        private static extern int SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
    }

}

[StructLayout(LayoutKind.Sequential)]
public struct COMBOBOXINFO {
    public Int32 cbSize;
    public RECT rcItem;
    public RECT rcButton;
    public int buttonState;
    public IntPtr hwndCombo;
    public IntPtr hwndEdit;
    public IntPtr hwndList;

    public static COMBOBOXINFO GetInfo(ComboBox combo) {
        COMBOBOXINFO info = new COMBOBOXINFO();
        info.cbSize = Marshal.SizeOf(info);
        SendMessageCb(combo.Handle, 0x164, IntPtr.Zero, out info);
        return info;
    }

    [DllImport("user32.dll", EntryPoint = "SendMessageW", CharSet = CharSet.Unicode)]
    private static extern IntPtr SendMessageCb(IntPtr hWnd, int msg, IntPtr wp, out COMBOBOXINFO lp);
}

//[StructLayout(LayoutKind.Sequential)]
//public struct RECT {
//  public int Left;
//  public int Top;
//  public int Right;
//  public int Bottom;
//}

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

防止 System.Window.Forms.ComboBox 的自动选择行为 (C#) 的相关文章

  • 在 Xamarin Android 中将图像从 URL 异步加载到 ImageView 中

    我有一个包含多个项目的 ListView 列表中的每个项目都应该有一个与之关联的图像 我创建了一个数组适配器来保存每个列表项并具有我希望加载的图像的 url 我正在尝试使用 Web 请求异步加载图像 并设置图像并在加载后在视图中更新它 但视
  • 如何在没有 Control.Invoke() 的情况下从后台线程修改控件属性

    最近 我们遇到了一些旧版 WinForms 应用程序 我们需要更新一些新功能 在专家测试该应用程序时 发现一些旧功能被破坏 无效的跨线程操作 现在 在您认为我是新手之前 我确实有一些 Windows 窗体应用程序的经验 我不是专家 但我认为
  • 嵌入式系统中的malloc [重复]

    这个问题在这里已经有答案了 我正在使用嵌入式系统 该应用程序在 AT91SAMxxxx 和 cortex m3 lpc17xxx 上运行 我正在研究动态内存分配 因为它会极大地改变应用程序的外观 并给我更多的力量 我认为我唯一真正的路线是为
  • FFMPEG Seeking 带来音频伪影

    我正在使用 ffmpeg 实现音频解码器 在读取音频甚至搜索已经可以工作时 我无法找到一种在搜索后清除缓冲区的方法 因此当应用程序在搜索后立即开始读取音频时 我没有任何工件 avcodec flush buffers似乎对内部缓冲区没有任何
  • 使用 Microsoft Graph API 订阅 Outlook 推送通知时出现 400 错误请求错误

    我正在尝试使用 Microsoft Graph API 创建订阅以通过推送通知获取 Outlook 电子邮件 mentions 我在用本文档 https learn microsoft com en us graph api subscri
  • 将字符串从非托管代码传递到托管

    我在将字符串从非托管代码传递到托管代码时遇到问题 在我的非托管类中 非托管类 cpp 我有一个来自托管代码的函数指针 TESTCALLBACK FUNCTION testCbFunc TESTCALLBACK FUNCTION 接受一个字符
  • 使用 C# 在 WinRT 中获取可用磁盘空间

    DllImport kernel32 dll SetLastError true static extern bool GetDiskFreeSpaceEx string lpDirectoryName out ulong lpFreeBy
  • 如何针对 Nancy 中的 Active Directory 进行身份验证?

    这是一篇过时的文章 但是http msdn microsoft com en us library ff650308 aspx paght000026 step3 http msdn microsoft com en us library
  • 为什么模板不能位于外部“C”块内?

    这是一个后续问题一个答案 https stackoverflow com questions 4866433 is it possible to typedef a pointer to extern c function type wit
  • 使用向量的 merge_sort 在少于 9 个输入的情况下效果很好

    不知何故 我使用向量实现了合并排序 问题是 它可以在少于 9 个输入的情况下正常工作 但在有 9 个或更多输入的情况下 它会执行一些我不明白的操作 如下所示 Input 5 4 3 2 1 6 5 4 3 2 1 9 8 7 6 5 4 3
  • 如何在 Team Foundation 上强制发表有意义的签入评论?

    我有一个开发团队有一个坏习惯 他们写道poor签入评论 当我们必须在团队基础上查看文件的历史记录时 这使得它成为一场噩梦 我已经启用了变更集评论政策 这样他们甚至可以在签到时留下评论 否则他们不会 我们就团队的工作质量进行了一些讨论 他们很
  • 检查 url 是否指向文件或页面

    我们需要以下内容 如果文件确实是文件 则从 URL 下载该文件 否则 如果它是一个页面 则什么也不做 举个简单的例子 我有以下命令来下载文件 My Computer Network DownloadFile http www wired c
  • 将日期参数传递给对 MVC 操作的 ajax 调用的安全方法

    我有一个 MVC 操作 它的参数之一是DateTime如果我通过 17 07 2012 它会抛出一个异常 指出参数为空但不能有空值 但如果我通过01 07 2012它被解析为Jan 07 2012 我将日期传递给 ajax 调用DD MM
  • GDK3/GTK3窗口更新的精确定时

    我有一个使用 GTK 用 C 语言编写的应用程序 尽管该语言对于这个问题可能并不重要 这个应用程序有全屏gtk window与单个gtk drawing area 对于绘图区域 我已经通过注册了一个刻度回调gtk widget add ti
  • Bing 地图运行时错误 Windows 8.1

    当我运行带有 Bing Map 集成的 Windows 8 1 应用程序时 出现以下错误 Windows UI Xaml Markup XamlParseException 类型的异常 发生在 DistanceApp exe 中 但未在用户
  • 如何使用 ReactiveList 以便在添加新项目时更新 UI

    我正在创建一个带有列表的 Xamarin Forms 应用程序 itemSource 是一个reactiveList 但是 向列表添加新项目不会更新 UI 这样做的正确方法是什么 列表定义 listView new ListView var
  • 将变量分配给另一个变量,并将一个变量的更改反映到另一个变量中

    是否可以将一个变量分配给另一个变量 并且当您更改第二个变量时 更改会瀑布式下降到第一个变量 像这样 int a 0 int b a b 1 现在 b 和 a 都 1 我问这个问题的原因是因为我有 4 个要跟踪的对象 并且我使用名为 curr
  • C++ 成员函数中的“if (!this)”有多糟糕?

    如果我遇到旧代码if this return 在应用程序中 这种风险有多严重 它是一个危险的定时炸弹 需要立即在应用程序范围内进行搜索和销毁工作 还是更像是一种可以悄悄留在原处的代码气味 我不打算writing当然 执行此操作的代码 相反
  • 为什么 strtok 会导致分段错误?

    为什么下面的代码给出了Seg 最后一行有问题吗 char m ReadName printf nRead String s n m Writes OK char token token strtok m 如前所述 读取字符串打印没有问题 但
  • 不同类型的指针可以互相分配吗?

    考虑到 T1 p1 T2 p2 我们可以将 p1 分配给 p2 或反之亦然吗 如果是这样 是否可以不使用强制转换来完成 或者我们必须使用强制转换 首先 让我们考虑不进行强制转换的分配 C 2018 6 5 16 1 1 列出了简单赋值的约束

随机推荐

  • 请求中的 URL 超出最大重试次数

    我正在尝试获取以下内容应用商店 gt 商业 https itunes apple com in genre ios business id6000 mt 8 import requests from lxml import html pag
  • Crystal Reports 文本截断详细信息部分中的最后一行

    我有一个 Crystal Report 11 文件 它是一封信 第一个详细信息部分包含一个大文本框 其中包含打印日期 地址块和称呼行 每隔一段时间 文本框的最后一行就会被切断 这样就看不到称呼了 这是非常不一致的 因为有时 我为系统中的一个
  • BlackBerry 中的图像按钮

    如何在 BlackBerry 中实现图像按钮 在这里 完整的代码 import net rim device api system Bitmap import net rim device api ui Graphics import ne
  • Python 将 args 转换为 kwargs

    我正在编写一个装饰器 它需要在调用它正在装饰的函数之前调用其他函数 装饰函数可以具有位置参数 但装饰器将调用的函数只能接受关键字参数 有人有一种将位置参数转换为关键字参数的便捷方法吗 我知道我可以获得修饰函数的变量名列表 gt gt gt
  • 正确的 javascript 继承

    我读了很多关于 javascript 中 继承 的文章 其中一些使用new当其他人推荐时Object Create 我读得越多 就越感到困惑 因为似乎存在无数的变体来解决继承问题 有人可以向我展示最受接受的方式 或者事实上的标准 如果有的话
  • 为什么动态更新 DOM 时 html 源不会改变

    我之前发过一个问题jQuery 在 IE 8 和 FF 3 5 8 中设置只读属性不一致 https stackoverflow com questions 2381621 jquery inconsistency in setting r
  • @error 指令不在 Laravel 视图中显示错误

    我正在研究自定义 Laravel 登录实现 我已从控制器返回错误 如下所示 credentials request gt only email password if Auth attempt credentials Authenticat
  • 如何在android上获取处理器编号

    大家好 我想获取android上的处理器编号 我可以这样做吗 int processporNum sysconf SC NPROCESSORS CONF 但每次在我的某些手机上返回值都是1 所以我不确定这个方法是否正确 是否有其他API可以
  • matplotlib 绘图 沿绘图线的标签

    matplotlib 社区的一份 假设我有一条直线 plot 37 45 0 67778 0 67778 k lw 1 2 我可以沿着线而不是在图例中向该线添加标签吗 即 类似于以下内容 但不是等高线图 只是普通的线图 下面是一个例子 只是
  • OpenSSl + PHP如何实现[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我需要在项目中使用 openSSL
  • 如何删除pandas中每组的第一行

    我有一个像这样的数据框 id values 0 1 3 1 1 6 2 1 3 3 2 7 4 2 6 5 2 3 6 2 9 我想根据删除每组的第一行id 结果应该是这样的 id values 1 1 6 2 1 3 4 2 6 5 2
  • 使用 JS 将任何标签内的文本复制到剪贴板[重复]

    这个问题在这里已经有答案了 我需要复制 p 标签内的文本 我尝试使用以下代码 HTML p Text to copy p
  • Subversion 中的合并比 Team Foundation System 中的合并更困难吗?

    我习惯了使用TFS 我的公司现在正在为一个新项目切换到SVN 主要原因是为了更好地将我们的java和 Net代码库合并在同一源代码控制下 我被赋予理解颠覆中的合并是困难的 杰夫提到了这一点 https blog stackoverflow
  • java中的cloneable接口有什么用?

    实现可克隆接口有什么用 因为它是一个标记接口 我总是可以在我的类中创建一个公共 Object clone 方法 可克隆接口的实际用途是什么 那是因为clone 方法抛出CloneNotSupportedException如果你的对象不是Cl
  • 如何调用我们的应用程序并获取来电的详细信息?

    如果我的应用程序中保存了任何号码 并且该用户在我的 iPhone 上呼叫我 那么我想通过屏幕调用我的应用程序 用户可以在屏幕上填写有关该呼叫的信息 例如呼叫持续时间 呼叫者姓名和一些应用程序特定的详细信息 请指导我如何在 iOS 中实现通话
  • 在 C 中声明数组而不指定大小

    当像这样声明一个数组时 int array 1 2 3 4 5 6 我收到一条错误消息 数组类型具有不完整的元素类型 到底是怎么回事 对于N维数组 N gt 0 需要定义N 1维的大小 只能留下一个维度供编译器确定 并且它必须是第一个维度
  • 逐行分割字符串并进行变量化,即将其分配给 GITHUB_OUTPUT - 工作流程

    Github 行动run调用 powershell 返回如下 Powershell返回函数 return psitem Key psitem Value 返回值被分配给 github 操作变量 returnvalue 返回包含一个列表key
  • 使用自定义项目模板在组合框中显示所选项目

    我使用此页面中的代码来设计我的组合框的样式 如何在鼠标悬停时设置组合框背景的样式 https stackoverflow com a 5564151 2848002 我更改了默认项目模板 但现在它们不会出现在所选值区域中 在下图中 您可以看
  • 如何从 XML 文件中删除不可见的垃圾字符

    我想读取一些 xml 文件 当我用记事本 写字板 MS Word 或任何浏览器打开这些文件时 它以其原始形式打开 但是当我尝试用 MS DOS 执行它时 会出现一个看不见的字符 如 被看到 我认为 正在创建一个错误 我发现错误 序言中不允许
  • 防止 System.Window.Forms.ComboBox 的自动选择行为 (C#)

    背景 我有一个Forms ComboBox with a DropDownStyle DropDown 我不使用AutoComplete 但我实现了类似的东西 它不仅过滤文本的开头 而且使用正则表达式并显示与输入的文本匹配的所有项目 这很好