簡體   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