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

Windows Forms ListView使用FindItemWithText查找数值时匹配异常问题

解决ListView的FindItemWithText误判重复ID问题

问题场景

有一个名为lst_Employees的ListView,搭配两个联动ComboBox:cmb_EmployeeID和cmb_EmployeeName。选择员工姓名后,ID会同步显示,点击按钮可将员工信息添加到ListView中。使用FindItemWithText判断员工是否已存在时出现误判:先添加ID为14的员工,再添加ID为1的员工会被提示重复;同理先加20-29的ID,再加2也会误判——原因是FindItemWithText仅做前缀匹配,不校验完整内容。

原问题代码

private void btn_EmployeeAdd_Click(object sender, EventArgs e)
{
    if (cmb_EmployeeName.SelectedIndex > 0)
    {
        ListViewItem foundItem = null;
        if (lst_Employees.Items.Count > 0)
        {
            foundItem = lst_Employees.FindItemWithText(cmb_EmployeeID.Text, false, 0);
            if (foundItem != null)
            {
                MessageBox.Show("Employee has already in the list", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }
        if (foundItem == null)
        {
            string name = cmb_EmployeeName.Text.Substring(0, cmb_EmployeeName.Text.IndexOf(" - ["));

            ListViewItem lvi = new ListViewItem();
            lvi.Text = cmb_EmployeeID.Text;
            lvi.SubItems.Add(name); 
            lst_Employees.Items.Add(lvi);
            cmb_EmployeeName.SelectedIndex = 0;
        }
    }
    else
    {
        MessageBox.Show("Please select an employee.");
    }
}

解决方案

方法1:遍历ListViewItems做精确字符串匹配

直接遍历列表项,对比每个项的ID文本与目标ID完全一致,避免前缀匹配问题:

private void btn_EmployeeAdd_Click(object sender, EventArgs e)
{
    if (cmb_EmployeeName.SelectedIndex > 0)
    {
        bool isExists = false;
        string targetId = cmb_EmployeeID.Text;
        
        // 精确匹配每个项的ID文本
        foreach (ListViewItem item in lst_Employees.Items)
        {
            if (item.Text.Equals(targetId, StringComparison.Ordinal))
            {
                isExists = true;
                break;
            }
        }

        if (isExists)
        {
            MessageBox.Show("Employee has already in the list", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            return;
        }

        // 添加新员工逻辑
        string name = cmb_EmployeeName.Text.Substring(0, cmb_EmployeeName.Text.IndexOf(" - ["));
        ListViewItem lvi = new ListViewItem();
        lvi.Text = targetId;
        lvi.SubItems.Add(name); 
        lst_Employees.Items.Add(lvi);
        cmb_EmployeeName.SelectedIndex = 0;
    }
    else
    {
        MessageBox.Show("Please select an employee.");
    }
}

方法2:用LINQ简化精确匹配判断

如果项目支持LINQ,可以用更简洁的代码实现:

private void btn_EmployeeAdd_Click(object sender, EventArgs e)
{
    if (cmb_EmployeeName.SelectedIndex > 0)
    {
        string targetId = cmb_EmployeeID.Text;
        bool isExists = lst_Employees.Items.Cast<ListViewItem>().Any(item => item.Text == targetId);

        if (isExists)
        {
            MessageBox.Show("Employee has already in the list", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            return;
        }

        // 添加新员工逻辑
        string name = cmb_EmployeeName.Text.Substring(0, cmb_EmployeeName.Text.IndexOf(" - ["));
        ListViewItem lvi = new ListViewItem();
        lvi.Text = targetId;
        lvi.SubItems.Add(name); 
        lst_Employees.Items.Add(lvi);
        cmb_EmployeeName.SelectedIndex = 0;
    }
    else
    {
        MessageBox.Show("Please select an employee.");
    }
}

方法3:转换为数值类型匹配(推荐)

如果ID是数值类型(如int),将字符串转换为数值后对比,彻底避免字符串格式带来的匹配问题:

private void btn_EmployeeAdd_Click(object sender, EventArgs e)
{
    if (cmb_EmployeeName.SelectedIndex > 0)
    {
        // 先校验ID格式
        if (!int.TryParse(cmb_EmployeeID.Text, out int targetId))
        {
            MessageBox.Show("Invalid Employee ID format.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return;
        }

        // 数值精确匹配
        bool isExists = lst_Employees.Items.Cast<ListViewItem>().Any(item => 
            int.TryParse(item.Text, out int existingId) && existingId == targetId);

        if (isExists)
        {
            MessageBox.Show("Employee has already in the list", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            return;
        }

        // 添加新员工逻辑
        string name = cmb_EmployeeName.Text.Substring(0, cmb_EmployeeName.Text.IndexOf(" - ["));
        ListViewItem lvi = new ListViewItem();
        lvi.Text = targetId.ToString();
        lvi.SubItems.Add(name); 
        lst_Employees.Items.Add(lvi);
        cmb_EmployeeName.SelectedIndex = 0;
    }
    else
    {
        MessageBox.Show("Please select an employee.");
    }
}

说明

FindItemWithText的默认逻辑是前缀匹配,只要项文本以目标字符串开头就会被命中,这是误判的核心原因。上述三种方法都通过精确匹配解决了问题,其中数值类型匹配的方式最可靠,能同时处理ID带前导零等特殊字符串格式的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 23:53:19