如何在C#

时间:2018-09-20 08:13:24

标签: c#

我有一个列表视图名称listView1,它包含计算机ID及其一些信息。所以我要做的是我有一个文本框名称filterbox,当我写东西将其过滤时,它可以正常工作。我的问题是只是寻找第一列而不是其他。例如;

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();
                }
            }
        }

3 个答案:

答案 0 :(得分:3)

这就像迭代子项一样简单

foreach (ListViewItem item in listView1.Items)
   foreach (ListViewItem.ListViewSubItem subitem in item.SubItems)
      if (subitem.Text.Equals(filterbox.Text, StringComparison.OrdinalIgnoreCase))
      {
         item.BackColor = SystemColors.Highlight;
         item.ForeColor = SystemColors.HighlightText;
         break;
      }

注意,您在这里还有其他事情要做,但是请留意这些细节

更新

要进行过滤,您可以使用一些linq

if (filterbox.Text == "")
{
   return;
}

var list = listView1.Items
                    .Cast<ListViewItem>()
                    .Where(
                        x => x.SubItems
                              .Cast<ListViewItem.ListViewSubItem>()
                              .Any(y => y.Text.Contains(filterbox.Text)))
                    .ToArray();
listView1.Items.Clear();
listView1.Items.AddRange(list);

答案 1 :(得分:2)

萨鲁曼答案的核心工作原理非常好:使用linq将所有符合条件的项目复制到一个可枚举的集合中,清除列表视图项,并AddRange进行分类。

但是,为使工作正常,需要进行一些更正。

首先:我们需要将整套项目存储在某个地方。同类最佳的变量:

List<ListViewItem> allItems = new List<ListViewItem>();

添加完全套项目后,我们需要填充它:

allItems.Clear();
allItems.AddRange(listView1.Items.Cast<ListViewItem>());

现在,我们可以对filterTextbox的TextChanged事件进行编码了;这里我们总是使用完整的数据集:

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
}

对Saruman表示敬意,后者用必要的Casts编写了linq!

顺便说一句:我们should并确实使用Cast而不是OfType,因为我们可以确定类型。 Cast快一点。

答案 2 :(得分:1)

您可以将列表视图与数据表绑定。请参阅bind list-view with data-table。在文本框“文本更改/控制离开”事件上,对数据表应用过滤器。由于它将数据源绑定到数据表,因此将负责更新列表视图的项目。

listView1.ItemsSource = dataTable.DefaultView;

使用以下查询过滤数据。

DataView dv = new DataView(yourDatatable);
dv.RowFilter = "query"; // query example = "id = 10"

让我知道是否有帮助。 :)