繁体   English   中英

当数据源是列表(C#)时,通过文本框过滤DataGridView

[英]Filter DataGridView by a textbox when its datasource is a List (C#)

我正在尝试创建一个文本框样式过滤器,该过滤器仅允许我在dataGridView表中显示具有选定匹配条件的1行。

在此处输入图片说明

该表当前通过数据源绑定到列表对象。

public static List<NpcDrop> npcDrops = new List<NpcDrop>();
//populate npcDrops
dataGridView3.DataSource = Program.npcDrops;

以此方式进行设置,以便我可以在dataGridView中编辑值,并且基础npcDrops列表将在单元格更改时自动更新。 列表稍后保存回到文件中。

因此,我无法将列表转换为DataTable或任何其他对象,因为这会破坏dataGridView与列表之间的关系。 我曾考虑过将列表更改为DataTable,然后再将其更改回List类型,但这似乎是不可能的。

我尝试通过多种方式解决该问题:

a)使用BindingSource

BindingSource bs = new BindingSource();
bs.DataSource = Program.npcDrops;
bs.Filter = "npcId like '201001'";
dataGridView3.DataSource = bs;

但是,似乎未应用筛选器(主要是由于基于List的BindingSource不是IEnumerable的事实。

b)通过将我的数据源转换为数据表,然后使用RowFilter功能

private void searchId_TextChanged(object sender, EventArgs e)
{
    (dataGridView3.DataSource as DataTable).DefaultView.RowFilter = 
    string.Format("npcId='{0}'", searchId.Text);
}

然而,这给了我对象引用未设置为对象的实例。 错误,似乎无法将dataGridView强制转换为DataTable。

我的想法真的用光了,我想知道是否有人可以帮助^^。

我猜您可能是在说“搜索”而不是“过滤器”。 如果您想在用户键入字符后立即“搜索”某些内容,则在大多数情况下,当用户在文本框中键入单个字符时,将触发searchId_TextChange事件。 在这种情况下,似乎代码正在从单个字符“过滤”“ Id”。 除非表中有一个单元格等于用户键入的值(在本示例中因为单个字符而没有),否则这很可能使用户处于“空”状态,因为过滤器将不返回任何匹配项。

因此,由于您只想显示一行,所以直到用户键入“完全”完整的数字后,该行才会出现。 在应用过滤器之前,可能要等到用户键入了x个字符后,这才是有益的。 或者只是在文本框旁边添加一个“搜索”按钮。 我猜这可能对用户更友好。

最后,为了提供帮助,下面是两个使用List<T>DataTable作为两个DataGridViewsDataTable DataSources示例,我将假设NpcDrop属性IDint 在此示例中, ID是一个int DataTable示例中, ID被定义为string 添加几个文本框,该窗体可能如下所示。

在此处输入图片说明

左侧的网格具有List<NcpDrop>作为数据源。 右侧的网格使用DataTable作为DataSource 最初, fullNPCDropsListgridTable用相同的数据填充。 连接两个文本框TextChanged事件以“过滤”网格。

当对List<NcpDrop>应用“过滤器”时,将创建一个新的List<NcpDrop> filterList ,并用所有匹配的ID填充。 此新的List<NcpDrop>用作网格DataSource

将“过滤器”应用于DataTable将从初始DataTalbe创建一个新的DataView filterData并根据文本框中的文本将RowFilter应用于DataView 然后将此DataView用作网格的DataSource。

从图片(下图)可以看出,左网格将保持“空”,直到用户键入“整数”。 另一方面,当用户键入更多字符时,右侧的网格将过滤列表项。 右侧的网格显示所有带有五(5)位数字的“ 20102”项目。 在用户键入第六(6)位数字之前,左侧的网格将保持空白。

在此处输入图片说明

总之,从用户的角度来看,确切的要求是什么以及什么是最佳方法尚不清楚。 如果用户正在搜索一个数字而数据是一个数字,我想您将需要做更多的工作,因为如果不使用均等,小于,大于等功能,此功能将不可用。

List<NpcDrop> fullNPCDropsList;
DataTable gridTable;

public Form1() {
  InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e) {
  fullNPCDropsList = GetData1();
  dgvListData.DataSource = fullNPCDropsList;
  gridTable = GetData2();
  dgvDataTableData.DataSource = gridTable;
}

private List<NpcDrop> GetData1() {
  List<NpcDrop> drop = new List<NpcDrop>();
  int start = 201000;
  for (int i = 0; i < 100; i++) {
    drop.Add(new NpcDrop(++start));
  }
  return drop;
}

private DataTable GetData2() {
  DataTable dt = new DataTable();
  dt.Columns.Add("ID", typeof(string));
  int start = 201000;
  for (int i = 0; i < 100; i++) {
    dt.Rows.Add((++start).ToString());
  }
  return dt;
}

private void txtListSearchBox_TextChanged(object sender, EventArgs e) {
  if (txtListSearchBox.Text == "") {
    dgvListData.DataSource = fullNPCDropsList;
  }
  else {
    if (int.TryParse(txtListSearchBox.Text, out int value)) {
      List<NpcDrop> filterList = fullNPCDropsList.FindAll(x => x.ID.Equals(value));
      dgvListData.DataSource = filterList;
    }
  }
}

private void txtDTSearchBox_TextChanged(object sender, EventArgs e) {
  if (txtDTSearchBox.Text == "") {
    dgvDataTableData.DataSource = gridTable;
  }
  else {
    DataView filterData = new DataView(gridTable);
    filterData.RowFilter = "ID LIKE '%" + txtDTSearchBox.Text + "%'";
    dgvDataTableData.DataSource = filterData;
  }
}

希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM