我有一个包含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");
}
}
答案 0 :(得分:2)
我已经更新了你的代码了。由于我没有完全理解它的用途,因此删除了突出显示逻辑,但您可以轻松地将其重新置于原位。
以下代码与您的格式相同。唯一的例外是为了测试目的而实施的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();
}
答案 1 :(得分:2)
您不必再做所有这些了。它具有内置功能。它搜索所有列。
ListViewItem foundItem = listJobs.FindItemWithText(txtJobSearch.Text.ToLower());
if (foundItem != null)
{
foundItem.BackColor = Color.Yellow;
foundItem.Selected = true;
}
答案 2 :(得分:1)
我更改了函数以返回索引到找到的项目,但也选择并定位到视图中。这是用于化学检测和紧急响应查找的代码,这就是列表视图被命名为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;
}