我有兴趣使用 DropDownStyle = DropDown
删除组合框的文本选择。
当我添加/删除或关闭 DropPown 时,该项目被选中。
我无法清除所选文本。你知道怎么做吗?
此代码不起作用:
comboBox.SelectionLenght = 0;
comboBox.SelectionStart = comboBox.Text.Legnth;
comboBox.Select(0,0);
我可以看到此行之后的文本突出显示:
selectedComboBox.Items.Add(redCompetitorName);
答案 0 :(得分:2)
您可以推迟 Select()
方法的执行,在 SelectedIndexChanged
事件处理程序中调用 BeginInvoke()(或 SelectionChangedCommitted,如果您希望这仅在用户手动选择一个项目。
通过推迟执行(此动作在消息循环中排队),Select()
动作仅在设置并突出显示ComboBox.Text
后才执行。因此,您的命令不会被默认行为覆盖。
private void comboBox_SelectedIndexChanged(object sender, EventArgs e)
{
// Set the caret to the start of the ComboBox text
BeginInvoke(new Action(()=> comboBox.Select(0, 0)));
// OR - set the caret to the end of the text instead
BeginInvoke(new Action(()=> comboBox.Select(int.MaxValue, 0)));
}
这个概念当然适用于其他情况。
您可以在其他情况下使用此方法,当您需要在 UI 中执行操作时,该操作仅在当前(或已调度 操作的当前序列)完成后执行。< /p>
如果您想要一个更参与的解决方案,以防止组合框中的所有类型的选择突出显示,您可以使用从组合框派生的自定义控件,get the Handle of its Edit Control,使用 {{3}拦截它的消息。覆盖 WndProc 以处理 NativeWindow 并调用 EM_SETSEL 以删除选择(仅当起始位置 > 0 时,否则您可能会陷入具有效果的奇怪自动循环中< /em> 通常被称为 StackOverflow :)
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
[DesignerCategory("code")]
public class ComboBoxNoFocus : ComboBox
{
IntPtr editHandle = IntPtr.Zero;
private EditNativeWindow editControl = null;
public ComboBoxNoFocus() { }
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
editHandle = GetComboBoxEditInternal(this.Handle);
editControl = new EditNativeWindow(editHandle);
}
public class EditNativeWindow : NativeWindow
{
private const int EM_SETSEL = 0x0B1;
public EditNativeWindow() : this(IntPtr.Zero) { }
public EditNativeWindow(IntPtr handle)
{
if (handle != IntPtr.Zero) {
this.AssignHandle(handle);
}
}
protected override void WndProc(ref Message m)
{
switch (m.Msg) {
case EM_SETSEL:
int pos = m.LParam.ToInt32();
if (pos > 0) {
PostMessage(this.Handle, EM_SETSEL, 0, 0);
}
return;
default:
// Other operations
break;
}
base.WndProc(ref m);
}
}
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
internal static extern bool GetComboBoxInfo(IntPtr hWnd, ref COMBOBOXINFO pcbi);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
[StructLayout(LayoutKind.Sequential)]
internal struct COMBOBOXINFO
{
public int cbSize;
public Rectangle rcItem;
public Rectangle rcButton;
public int buttonState;
public IntPtr hwndCombo;
public IntPtr hwndEdit;
public IntPtr hwndList;
public void Init() => this.cbSize = Marshal.SizeOf<COMBOBOXINFO>();
}
internal static IntPtr GetComboBoxEditInternal(IntPtr cboHandle)
{
var cbInfo = new COMBOBOXINFO();
cbInfo.Init();
GetComboBoxInfo(cboHandle, ref cbInfo);
return cbInfo.hwndEdit;
}
}
答案 1 :(得分:1)
在选择新项目后,使用组合框的 SelectedIndexChanged
事件将焦点设置到表单中的另一个控件。
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
button1.Focus();
}