当DataGridView的数据源为列表时,按文本框过滤DataGridView(C#)

当DataGridView的数据源为列表时,按文本框过滤DataGridView(C#),c#,list,filter,datagridview,C#,List,Filter,Datagridview,我正在尝试创建一个文本框样式的过滤器,该过滤器将允许我在dataGridView表中仅显示具有选定匹配条件的1行 该表当前通过数据源绑定到列表对象 public static List<NpcDrop> npcDrops = new List<NpcDrop>(); //populate npcDrops dataGridView3.DataSource = Program.npcDrops; 但是,似乎没有应用过滤器(主要原因是基于列表的BindingSource不

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

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

public static List<NpcDrop> npcDrops = new List<NpcDrop>();
//populate npcDrops
dataGridView3.DataSource = Program.npcDrops;
但是,似乎没有应用过滤器(主要原因是基于列表的BindingSource不是IEnumerable

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

private void searchId_TextChanged(object sender, EventArgs e)
{
    (dataGridView3.DataSource as DataTable).DefaultView.RowFilter = 
    string.Format("npcId='{0}'", searchId.Text);
}
然而,这给了我对象引用未设置为对象的实例。错误,因为它似乎无法将dataGridView强制转换为DataTable


我真的没什么主意了,我想知道是否有人能帮忙。^^。

我猜你的意思可能是“搜索”而不是“过滤”。如果您希望在用户键入字符后立即“搜索”某个内容,那么在大多数情况下,当用户在文本框中键入单个字符时,
searchId\u TextChange
事件将触发。在这种情况下,代码似乎正在从单个字符中“过滤”Id。除非表中有一个单元格等于用户键入的值(本例中没有,因为它是一个字符)…否则这很可能会让用户将网格保持为“空”状态,因为筛选器不会返回任何匹配项

因此,由于您似乎只需要一行,因此在用户输入“精确”的完整数字之前,该行不会出现。在应用过滤器之前,最好等待用户输入x个字符。或者简单地在文本框旁边添加一个“搜索”按钮。我猜这可能更方便用户

最后,为了提供帮助,下面是将
列表
数据表
作为
数据源
使用到两个
数据网格视图
的两个示例,我假设
NpcDrop
属性
ID
int
。在本例中,
ID
是一个
int
。在
DataTable
示例中,
ID
被定义为
字符串。添加几个文本框,表单可能如下所示

左侧的网格有一个
列表
作为数据源。右侧的网格将
数据表
用作
数据源
。最初,
fullNPCDropsList
gridTable
用相同的数据填充。两个文本框
TextChanged
事件被连接起来以“过滤”网格

当为
列表
应用“过滤器”时,将创建一个新的
列表
过滤器列表
,并填充所有匹配的
ID
。这个新的
列表
用作网格
数据源

将“筛选器”应用于
数据表
时,将从初始的
数据表
创建一个新的
数据视图
筛选器数据
,并根据文本框中的文本将
行筛选器
应用于
数据视图
。然后将此
DataView
用作网格的数据源

从下图中可以看出,在用户输入“整数”之前,左侧网格将保持“空”。另一方面,当用户键入更多字符时,右侧的网格将过滤列表项。右侧的网格显示所有类似于“20102”的项目,有五(5)位数字。在用户输入第六(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;
  }
}
List fullNPCDropsList;
数据表网格表;
公共表格1(){
初始化组件();
}
私有void Form1\u加载(对象发送方、事件参数e){
fullNPCDropsList=GetData1();
dgvListData.DataSource=fullNPCDropsList;
gridTable=GetData2();
dgvDataTableData.DataSource=gridTable;
}
私有列表GetData1(){
列表放置=新建列表();
int start=201000;
对于(int i=0;i<100;i++){
添加(新的NpcDrop(++start));
}
返回下降;
}
私有数据表GetData2(){
DataTable dt=新的DataTable();
添加(“ID”,类型(字符串));
int start=201000;
对于(int i=0;i<100;i++){
Add(++start.ToString());
}
返回dt;
}
私有void txtListSearchBox_text已更改(对象发送方,事件参数e){
如果(txtListSearchBox.Text==“”){
dgvListData.DataSource=fullNPCDropsList;
}
否则{
if(int.TryParse(txtListSearchBox.Text,out int值)){
List filterList=fullNPCDropsList.FindAll(x=>x.ID.Equals(value));
dgvListData.DataSource=过滤器列表;
}
}
}
私有void txtDTSearchBox_text已更改(对象发送方,事件参数e){
如果(txtDTSearchBox.Text==“”){
dgvDataTableData.DataSource=gridTable;
}
否则{
DataView filterData=新数据视图(gridTable);
filterData.RowFilter=“ID类似“%”+TXTDSearchBox.Text+“%”;
dgvDataTableData.DataSource=filterData;
}
}

希望这能有所帮助。

你能不能只使用ICollectionView和内置过滤器?如果我将列表转换为ICollectionView,对表所做的任何更改都不会反映在我的列表上,这会中断我与列表之间的双向通信。你试过使用吗?互联网上有一个样本,它实际上与列表数据的System.Data数据视图。它允许排序和过滤。我以前在工作中用过。我不记得在哪里找到的。嗨!首先,谢谢你的回答。我不得不使用第一种方法,因为我
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;
  }
}