【问题标题】:Searching a muticolumn ListView C#搜索多列 ListView C#
【发布时间】:2014-07-25 20:09:11
【问题描述】:

我有一个包含 4 列的 ListView 控件。文件名、ID、类型、项目。我通过读取包含必要字段的管道分隔文件将项目添加到 ListView。一切正常,ListView 显示我的数据。但是,我想添加一个搜索功能,以便用户可以搜索 ListView 并将其项目过滤为仅与搜索文本匹配的项目。如果可能的话,我希望能够在他们键入时过滤列表。我的列表视图正在使用详细信息视图,其中定义的列与上述 4 列匹配。

到目前为止,我已经尝试了以下代码,但无法弄清楚如何使其工作。 我的 restoreAllItems 方法工作正常,并恢复列表视图以包含所有项目,就好像搜索文本框为空一样。

这是一个获胜表格应用程序

有人可以帮我指出正确的方向吗?
提前谢谢!!!

private void txtJobSearch_TextChanged(object sender, EventArgs e)
    {
        // Search items in our Jobs ListView, remove those that do not match search
        if (txtJobSearch.Text != String.Empty)
        {
            for (int i = listJobs.Items.Count - 1; i >= 0; i--)
            {                    
                if (listJobs.Items[i].Text.ToLower().Contains(txtJobSearch.Text.ToLower()))
                {
                    listJobs.Items[i].BackColor = SystemColors.Highlight;
                    listJobs.Items[i].ForeColor = SystemColors.HighlightText;
                }
                else
                {
                    for (int x = listJobs.Items[i].SubItems.Count - 1; x >= listJobs.Items[i].SubItems.Count; x--)
                    {
                        if (listJobs.Items[i].SubItems[x].Text.ToLower().Contains(txtJobSearch.Text.ToLower()))
                        {
                            listJobs.Items[i].BackColor = SystemColors.Highlight;
                            listJobs.Items[i].ForeColor = SystemColors.HighlightText;
                        }
                        else
                        {
                            listJobs.Items[i].Remove();
                        }
                    }                    
                }
            }
        }
        else
        {
            restoreAllItems("jobs");
        }
    }

【问题讨论】:

  • 我猜这是winforms
  • @UweKeim 是的,抱歉更新了问题以明确说明
  • 我猜你已经知道了,但不管怎样。有各种(一些相当昂贵的)第三方产品可以真正使您的应用程序看起来很棒,并具有许多花哨的功能,并且可以让您摆脱像您自己在这里谈论的那样做事情的苦差事。
  • @RenniePet 如果我不能一路学习,那么编写应用程序有什么意义。编程很有趣,但是当我遇到困难时,有时我需要一只有用的手来指引我正确的方向。不使用 3rd 方产品,即使需要一整晚,我都会弄清楚的。
  • 好的,给你更多的权力。

标签: c# .net winforms listview


【解决方案1】:

我已经稍微更新了您的代码。由于我不完全理解它的目的,因此删除了突出显示逻辑,但您可以轻松地将其放回原处。 以下代码在与您相同的表单上运行。唯一的例外是为测试目的而实现的 ReinitList() 方法。

// check if current item matches search string
private bool ItemMatches(ListViewItem item, string text)
{
    bool matches = false;

    matches |= item.Text.ToLower().Contains(text.ToLower());

    if (matches)
    {
        return true;
    }

    foreach (ListViewItem.ListViewSubItem subitem in item.SubItems)
    {
        matches |= subitem.Text.ToLower().Contains(text.ToLower());
        if (matches)
        {
            return true;
        }
    }

    return false;
}

private void txtJobSearch_TextChanged(object sender, EventArgs e)
{
    // prevent flickering
    listJobs.BeginUpdate();

    // restore all items in case user deletes some characters in the textbox
    ReinitList();

    string search = txtJobSearch.Text;
    // Search items in our Jobs ListView, remove those that do not match search
    if (search != String.Empty)
    {
        for (int i = listJobs.Items.Count - 1; i >= 0; i--)
        {
            ListViewItem currentItem = listJobs.Items[i];
            if (ItemMatches(currentItem, search))
            {
                // highlight, or move highlighting to ItemMatches
            }
            else
            {
                listJobs.Items.RemoveAt(i);
            }
        }
    }

    listJobs.EndUpdate();
}


private void ReinitList()
{
    listJobs.Items.Clear();
    for (int i = 0; i < 50; i++)
    {
        ListViewItem item = new ListViewItem(i.ToString());
        item.SubItems.Add("sub " + i.ToString());
        item.SubItems.Add("sub a" + i.ToString());
        item.SubItems.Add("sub b" + i.ToString());

        listJobs.Items.Add(item);
    }
}

private void Form1_Load(object sender, EventArgs e)
{
    ReinitList();
}

【讨论】:

  • 完美运行!感谢您的帮助!
【解决方案2】:

您不必再做所有这些了。它有一个内置的功能。它搜索所有列。

ListViewItem foundItem = listJobs.FindItemWithText(txtJobSearch.Text.ToLower());
if (foundItem != null)
{
    foundItem.BackColor = Color.Yellow;
    foundItem.Selected = true;
}

【讨论】:

    【解决方案3】:

    我更改了函数以将索引返回到找到的项目,但也可以选择并定位到视图中。这是用于化学检测和紧急响应查找的代码,这就是列表视图被命名为 listViewChemical 的原因。

    private int ItemMatches(string text)
    {
            bool matches = false;
            int idx      = -1;
            for (int i   = chemicalSearchIndex; i < listViewChemical.Items.Count; i++)
            {
                ListViewItem item = listViewChemical.Items[i];
                matches          |= item.Text.ToLower().Contains(text.ToLower());
                if (matches)
                {
                    idx = item.Index;
                    break;
                }
                if (!checkBoxFormulaOnly.Checked)
                {
                    foreach (ListViewItem.ListViewSubItem subitem in item.SubItems)
                    {
                        matches |= subitem.Text.ToLower().Contains(text.ToLower());
                        if (matches)
                        {
                            idx = item.Index;
                            break;
                        }
                    }
                }
            }
    
            if (idx >= 0)
            {
                listViewChemical.Items[idx].EnsureVisible();
                listViewChemical.Items[idx].Selected = true;
                listViewChemical.Select();
                chemicalSearchIndex      = idx + 1;
                if (chemicalSearchIndex >= listViewChemical.Items.Count)
                {
                    chemicalSearchIndex  = 0;  //go back to top
                }
            }
            else
            {
                //No matches
                chemicalSearchIndex = 0;  //set next find or next to start at the beginning of the list
            }
            return idx;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-11
      • 2022-01-15
      • 1970-01-01
      • 1970-01-01
      • 2015-08-31
      • 1970-01-01
      • 1970-01-01
      • 2013-06-02
      相关资源
      最近更新 更多