的System.Window.Forms.ComboBox(C#)防止自动选择行为 [英] Prevent AutoSelect behavior of a System.Window.Forms.ComboBox (C#)

查看:471
本文介绍了的System.Window.Forms.ComboBox(C#)防止自动选择行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景:

我有一个 Forms.ComboBox DropDownStyle =下拉

我不使用自动完成,但我实现类似的东西不只是过滤文本的开头,但使用正则表达式匹配显示输入的文字,所有的项目。这工作得很好。

I don't use AutoComplete, but I implemented something similar which does not only filter the beginning of the text, but uses a regular expression and shows all items which match the text entered. This works fine.

然而,当我键入一个匹配项的第一个字母,将组合框回落到其原来的行为,并设置 DroppedDown = TRUE 和经销商的选择第一项,并完成对所选择的项目(类似于 AutoCompleteMode 追加)。我要的是没有自动选择和自动完成。

However, when I type the first letter of a matching item, the ComboBox falls back to its original behavior and sets DroppedDown = true and auto selects the first entry and completes the text to match the selected item (similar to AutoCompleteMode Append). What I want is no auto selection and auto completion.

我找到了到目前为止,我无论如何都必须防止的SendMessage() CB_FINDSTRING CB_FINDSTRINGEXACT CB_FINDSTRING C $ C>( MSDN链接)。

What I found so far is, that I somehow have to prevent SendMessage() with CB_FINDSTRING of being called and replace CB_FINDSTRING with CB_FINDSTRINGEXACT (MSDN Link).

我觉得我有扩展ComboBox类,但我不知道我要重写哪些方法。 。我和C#.NET框架V3.5工作

I think I have to extend the ComboBox class, but I'm not sure which methods I have to override. I'm working with C# .NET Framework v3.5.

问题:


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

  • How do I extend a Windows.Forms.ComboBox to prevent the auto select behavior?

链接:

如何防止自动选择在组合框上,除了准确的下拉匹配(没有帮助我)

推荐答案

试试这个:

// 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

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

        public static void Register(ComboBox combo) {

            Data data = new Data() { combo = combo };
            Action assign = () => {
                COMBOBOXINFO info = new COMBOBOXINFO();
                info.cbSize = Marshal.SizeOf(info);
                SendMessageCb(combo.Handle, 0x164, IntPtr.Zero, out info);

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

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

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

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

    private struct COMBOBOXINFO {
        public Int32 cbSize;
        public RECT rcItem;
        public RECT rcButton;
        public int buttonState;
        public IntPtr hwndCombo;
        public IntPtr hwndEdit;
        public IntPtr hwndList;
    }

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

    private class NW : NativeWindow {
        public NW(IntPtr handle) {
            this.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);
        }
    }
}

// try typing 'a' in both boxes, then resizing the window
// The top combo box will keep 'a', the bottom one will select 'Apple'
// Similarly, try opening and closing the dropdown list, or changing focus.
public class Form8 : Form {

    ComboBox combo = new ComboBox() { Dock = DockStyle.Top }; // modified
    Button btn1 = new Button { Text = "Set Text Button", Dock = DockStyle.Top };
    Button btn2 = new Button { Text = "Get Text Button", Dock = DockStyle.Top };
    Button btn3 = new Button { Text = "Get Selected Text Button", Dock = DockStyle.Top };
    ComboBox combo1 = new ComboBox() { Dock = DockStyle.Top }; // regular
    public Form8() {
        combo.AutoSelectOff();

        this.Controls.Add(btn3);
        this.Controls.Add(btn2);
        this.Controls.Add(btn1);
        this.Controls.Add(combo1);
        this.Controls.Add(combo);
        combo1.Items.AddRange(new Object[] { "Apple", "Banana" });
        combo.Items.AddRange(new Object[] { "Apple", "Banana" });
        btn1.Click += delegate {
            combo.Text = "Abcd";
        };
        btn2.Click += delegate {
            MessageBox.Show("" + combo.Text);
        };

        btn3.MouseEnter += delegate {
            if (combo.SelectedText.Length > 0)
                MessageBox.Show("" + combo.SelectedText);
        };
    }
}

这篇关于的System.Window.Forms.ComboBox(C#)防止自动选择行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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