You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinForms ComboBox自定义文本与筛选功能触发异常问题

WinForms 低操作成本ComboBox实现异常问题

我希望实现一款低操作成本的WinForms ComboBox,需满足以下行为要求:

  • 用户通过Tab切换、点击、输入等交互操作时,自动展开下拉列表
  • 根据ComboBox中的输入文本筛选下拉项(获焦时显示全部项)
  • 允许用户输入未在下拉列表中的自定义文本

已完成相关实现,但存在异常问题:当输入未匹配任何项的自定义文本后,若下拉列表处于展开状态,通过Esc键或点击外部控件使ComboBox失焦时,会触发ComboBox.ObjectCollection.cs文件第227行或第230行的异常。

注:实际场景中需处理对象列表,获取选中对象或自定义文本,但简化版仍会触发异常。已升级至WinForms 9版本,问题依旧;仅通过Tab键失焦时无异常,仅Esc或外部点击触发。

简化版实现代码

using System.Data;

namespace SearchComboBox
{
    public class MainForm : Form
    {
        private ComboBox itemsComboBox;
        private BindingSource itemsBindingSource;
        private DataTable itemsTable;
        private TextBox initialFocusTextBox;

        private static string[] items = {
            "First item",
            "Second item",
            "Third item",
            "Item 4",
            "Item 5",
        };

        public MainForm()
        {
            SuspendLayout();
            ClientSize = new Size(300, 150);

            initialFocusTextBox = new TextBox() {
                Anchor = AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Left,
                Location = new Point(12, 12),
                Size = new Size(276, 23),
                TabIndex = 0,
            };
            Controls.Add(initialFocusTextBox);

            itemsComboBox = new ComboBox() {
                Anchor = AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Left,
                Location = new Point(12, 41),
                Size = new Size(276, 23),
                TabIndex = 1,
            };
            Controls.Add(itemsComboBox);

            itemsTable = new DataTable();
            itemsTable.Columns.Add("Item", typeof(string));
            itemsTable.Columns.Add("Search", typeof(string));
            foreach (string item in items) {
                itemsTable.Rows.Add(item, item.ToLower());
            }

            itemsBindingSource = new BindingSource();
            itemsBindingSource.DataSource = itemsTable;

            itemsComboBox.DisplayMember = "Item";
            itemsComboBox.DataSource = itemsBindingSource;
            itemsComboBox.Click += itemsComboBox_Click;
            itemsComboBox.Enter += itemsComboBox_Enter;
            itemsComboBox.TextUpdate += itemsComboBox_TextUpdate;

            itemsComboBox.SelectedIndex = -1;
            itemsComboBox.Text = string.Empty;

            ResumeLayout(false);
            PerformLayout();
        }

        private void itemsComboBox_Click(object? sender, EventArgs e)
        {
            itemsComboBox.DroppedDown = true;
        }

        private void itemsComboBox_Enter(object? sender, EventArgs e)
        {
            var selectText = itemsComboBox.Text;

            itemsBindingSource.Filter = null;

            itemsComboBox.SelectedIndex = -1;
            itemsComboBox.Text = selectText;
            itemsComboBox.SelectAll();

            itemsComboBox.DroppedDown = true;
        }

        private void itemsComboBox_TextUpdate(object? sender, EventArgs e)
        {
            var selectText = itemsComboBox.Text;
            var selectionStart = itemsComboBox.SelectionStart;
            var selectionLength = itemsComboBox.SelectionLength;

            if (string.IsNullOrWhiteSpace(selectText))
            {
                itemsBindingSource.Filter = null;
            }
            else
            {
                itemsBindingSource.Filter = string.Format("Search LIKE '*{0}*'", selectText);
            }

            itemsComboBox.Text = selectText;
            itemsComboBox.SelectionStart = selectionStart;
            itemsComboBox.SelectionLength = selectionLength;

            itemsComboBox.DroppedDown = true;
        }
    }
}

.csproj配置

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net7.0-windows</TargetFramework>
    <Nullable>enable</Nullable>
    <UseWindowsForms>true</UseWindowsForms>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>
</Project>

异常堆栈信息

>   [Exception] System.Windows.Forms.dll!System.Windows.Forms.ComboBox.ObjectCollection.this[int].get(int index) Line 230   C#
    [Exception] System.Windows.Forms.dll!System.Windows.Forms.ComboBox.Text.get() Line 1250 C#
    [Exception] SearchComboBox.dll!SearchComboBox.MainForm.itemsComboBox_Enter(object sender, System.EventArgs e) Line 71   C#
    [Exception] System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.UpdateFocusedControl() Line 1644 C#
    [Exception] System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.AssignActiveControlInternal(System.Windows.Forms.Control value) Line 558 C#
    [Exception] System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.ActivateControl(System.Windows.Forms.Control control, bool originator) Line 423  C#
    [Exception] System.Windows.Forms.dll!System.Windows.Forms.ComboBox.ChildWndProc(ref System.Windows.Forms.Message m) Line 1713   C#
    [Exception] System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Callback(nint hWnd, Interop.User32.WM msg, nint wparam, nint lparam) Line 369    C#
    System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Callback(nint hWnd, Interop.User32.WM msg, nint wparam, nint lparam) Line 380    C#
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DefWndProc(ref System.Windows.Forms.Message m) Line 515  C#
    System.Windows.Forms.dll!System.Windows.Forms.ComboBox.ChildWndProc(ref System.Windows.Forms.Message m) Line 1810   C#
    System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Callback(nint hWnd, Interop.User32.WM msg, nint wparam, nint lparam) Line 369    C#
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.Interop.Mso.IMsoComponentManager.FPushMessageLoop(nuint dwComponentID, Interop.Mso.msoloop uReason, void* pvLoopData) Line 345   C#
    System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Interop.Mso.msoloop reason, System.Windows.Forms.ApplicationContext context) Line 1117  C#
    System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Interop.Mso.msoloop reason, System.Windows.Forms.ApplicationContext context) Line 981    C#
    SearchComboBox.dll!SearchComboBox.Program.Main() Line 14    C#

内容的提问来源于stack exchange,提问作者Milan Majer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 21:47:05