为了账号安全,请及时绑定邮箱和手机立即绑定

当 DataGridView 的数据源是 List (C#) 时

当 DataGridView 的数据源是 List (C#) 时

C#
摇曳的蔷薇 2021-11-07 19:11:15
我正在尝试创建一个文本框样式过滤器,它允许我在 dataGridView 表中仅显示具有选定匹配条件的 1 行。该表当前通过数据源绑定到列表对象。public static List<NpcDrop> npcDrops = new List<NpcDrop>();//populate npcDropsdataGridView3.DataSource = Program.npcDrops;这是这样设置的,所以我可以编辑dataGridView 中的值,底层的npcDrops列表会在单元格更改时自动更新。该列表稍后会保存回文件。因此,我无法将列表转换为 DataTable 或任何其他对象,因为这会破坏 dataGridView 和列表之间的关系。我曾考虑将列表更改为 DataTable,然后将其更改回 List 类型,但似乎不太可能做到。我尝试从各种方式解决这个问题:a) 使用 BindingSourceBindingSource bs = new BindingSource();bs.DataSource = Program.npcDrops;bs.Filter = "npcId like '201001'";dataGridView3.DataSource = bs;但是似乎没有应用过滤器(主要是由于基于 List的BindingSource不是IEnumerable。b) 通过将我的 DataSource 转换为 DataTable,然后使用 RowFilter 功能private void searchId_TextChanged(object sender, EventArgs e){    (dataGridView3.DataSource as DataTable).DefaultView.RowFilter =     string.Format("npcId='{0}'", searchId.Text);}然而,这给了我对象引用未设置为对象的实例。错误,因为它似乎无法将 dataGridView 转换为 DataTable。我真的没有想法了,我想知道是否有人可以提供帮助 ^^。
查看完整描述

1 回答

?
炎炎设计

TA贡献1808条经验 获得超4个赞

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

因此,由于看起来您想要一行,那么在用户输入“确切”完整数字之前,该行不会出现。在应用过滤器之前等待用户输入 x 个字符可能是有益的。或者只需在文本框旁边添加一个“搜索”按钮。我猜这可能对用户更友好。

最后,为了帮助,下面是使用的两个例子List<T>DataTable作为DataSources两个DataGridViews我将承担NpcDrop财产IDint。在这个例子中ID是一个int. 在DataTable示例中,ID定义为string。添加几个文本框,表单可能如下所示。

//img1.sycdn.imooc.com//6187b4820001d1d003450476.jpg

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

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

当一个“过滤器”被应用到DataTablea newDataView filterData是从初始创建的DataTalbe, aRowFilter被应用到DataView基于文本框中的文本。这DataView随后被用作一个数据源`到电网。

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

//img1.sycdn.imooc.com//6187b48f0001ce1303470482.jpg

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


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;

  }

}

希望这可以帮助。


查看完整回答
反对 回复 2021-11-07
  • 1 回答
  • 0 关注
  • 594 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信