我有一个列表视图名称listView1,它包含计算机ID和它们的一些信息。所以我想做的是我有一个文本框名称过滤框,当我写东西时它会过滤它,它工作得很好。我的问题是它只是寻找第一列不是其他列。例如;
PCNAME USER MODEL
AAAA JOHN DELL
BBBB MIKE TOSHIBA
CCCC ASH MONSTER
当我输入 BB 时,它只会显示第二行,并且工作正常,但如果我输入 DELL,它不会显示任何内容。
private void filterbox_TextChanged(object sender, EventArgs e)
{
if (filterbox.Text != "")
{
for (int i = listView1.Items.Count - 1; i >= 0; i--)
{
var item = listView1.Items[i];
if (item.Text.ToLower().Contains(filterbox.Text.ToLower()))
{
item.BackColor = SystemColors.Highlight;
item.ForeColor = SystemColors.HighlightText;
}
else
{
listView1.Items.Remove(item);
}
}
if (listView1.SelectedItems.Count == 1)
{
listView1.Focus();
}
}
}
Saruman 答案的核心效果很好:使用 linq 将符合条件的所有项目复制到可枚举集合中,清除列表视图项目并AddRange
好的。
然而,为了获得完全有效的解决方案,需要进行一些更正。
第一:我们需要将全套物品存储在某处。同类最佳变量:
List<ListViewItem> allItems = new List<ListViewItem>();
添加全套项目后我们需要填写它:
allItems.Clear();
allItems.AddRange(listView1.Items.Cast<ListViewItem>());
现在我们可以编写代码TextChanged
我们的filterTextbox的事件;这里我们总是使用完整的数据集:
private void filterbox_TextChanged(object sender, EventArgs e)
{
listView1.Items.Clear(); // clear all items we have atm
if (filterbox.Text == "")
{
listView1.Items.AddRange(allItems.ToArray()); // no filter: add all items
return;
}
// now we find all items that have a suitable text in any subitem/field/column
var list = allItems.Cast<ListViewItem>()
.Where( x => x.SubItems
.Cast<ListViewItem.ListViewSubItem>()
.Any(y => y.Text.Contains(filterbox.Text)))
.ToArray();
listView1.Items.AddRange(list); // now we add the result
}
向萨鲁曼致敬谁用必要的方法编写了 linqCasts
!
Btw: We should https://stackoverflow.com/questions/4015930/when-to-use-cast-and-oftype-in-linq并使用Cast
代替OfType
因为我们可以确定类型。Cast
是有点快。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)