的System.Window.Forms.ComboBox(C#)防止自动选择行为 [英] Prevent AutoSelect behavior of a 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 $ C匹配的文本$ C>追加)。我要的是没有自动选择和自动完成。
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 $ code>与
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屋!