如何从文本框搜索中向 dataGridView 输入多于 1 行

How to enter more than 1 row into dataGridView from textBox search

我正在使用以下代码在 accessdb 中搜索输入的文本框 ID,并将数据行返回到 dataGridView。当我搜索第二个ID时,GridView中的第一行被替换,如何让它保存多行?

该项目的最终目标是允许用户搜索任意数量的 ID,并将相应的数据行拉入 gridview,然后将所有数据保存到 csv 中。

 private void searchButton_Click(object sender, EventArgs e)
    {
        conn1.Open();

        //return ID, IMEI, ICCID, IMSI from dataBase
        OleDbCommand cmd1 = new OleDbCommand("Select ID, IMEI,ICCID, IMSI from TBL where ID=@param1", conn1);
        cmd1.Parameters.AddWithValue("@param1", txtScannedValue.Text);
        OleDbDataReader reader1;
        reader1 = cmd1.ExecuteReader();

        DataTable dt = new DataTable();
        dt.Load(reader1);

        //dataGridView1.DataSource= dt;
        if (dt.Rows.Count > 0)
        {
            ((DataTable)dataGridView1.DataSource).ImportRow(dt.Rows[0]);
        }
        else
        {
            MessageBox.Show("No Data Found");
        }

        //reset textBox
        txtScannedValue.Text = "";

        conn1.Close();
    }

您正在做的是 - 每次您按下 searchButton_Click 按钮时,您都是 运行 一个仅 returns 1 行(ID=@param1)的查询,然后您正在通过 .DataSource() 绑定将所有搜索行(由于查询在您的情况下始终为 1)插入到 dataGridView 中。 要解决这个问题,我建议您重新实现数据绑定:

我假设 DataTable 来自 ADO.NET,因此无需更改查询,您可以像这样绑定数据:

// this is pseudocode
private void searchButton_Click(object sender, EventArgs e) {

  var row = (DataGridViewRow) dataGridView1.Rows[0].Clone();

  var retrievedRow = getRowById(txtScannedValue.Text);
  if (retrievedRow is null) return;

  row.Cells[0].Value = retrievedRow.value1; // bind here you model fields
  row.Cells[1].Value = retrievedRow.value2;
  // ...

  dataGridView1.Rows.Add(row);
}

private void getRowById(string id) {
  conn1.Open();

  OleDbCommand cmd1 = new OleDbCommand("Select ID, IMEI, TekNum, BatchNum, ICCID, IMSI from TBLTest1 where ID=@param1", conn1);
  cmd1.Parameters.AddWithValue("@param1", id);
  OleDbDataReader reader1;
  reader1 = cmd1.ExecuteReader();
  DataTable dt = new DataTable();
  dt.Load(reader1);

  DataRow row;
  if (dt.Rows.Count > 0) {
    row = dt.Rows[0];
  }

  conn1.Close();
  return row;
}

我会使用 ListBox 或 ComboBox 来呈现它们可以通过可用 ID 识别的数据。要追加行,请使用 DataTable.ImportRow.

此处使用 ComboBox 来展示员工,DataGridView 最初填充了一个空的 DataTable。

单击按钮获取要附加到 DataGridView 的基础 DataTable 的行。

模型和数据操作

using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;

namespace AccessApplication.Classes
{
    public class EmployeesOperations
    {
        public static string ConnectionString =>
            "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=NorthWind.accdb";

        public static List<Employee> EmployeesList()
        {
            List<Employee> list = new List<Employee>();
            using var cn = new OleDbConnection { ConnectionString = ConnectionString };
            using var cmd = new OleDbCommand() { Connection = cn };

            cmd.CommandText = "SELECT EmployeeID, FirstName, LastName  FROM Employees";

            cn.Open();
            var reader = cmd.ExecuteReader();
            while (reader.Read())
            {
                list.Add(new Employee()
                {
                    Id = reader.GetInt32(0), 
                    FirstName = reader.GetString(1), 
                    LastName = reader.GetString(2)
                });
            }

            return list;
        }

        public static DataTable EmptyDataTable()
        {
            using var cn = new OleDbConnection { ConnectionString = ConnectionString };
            using var cmd = new OleDbCommand() { Connection = cn };

            cmd.CommandText = 
                "SELECT TOP 1 EmployeeID, FirstName, LastName FROM Employees";

            cn.Open();

            DataTable table = new DataTable();
            table.Load(cmd.ExecuteReader());
            table.Rows.Clear();

            return table;
        }
        public static DataTable SingleRow(int identifier)
        {
            using var cn = new OleDbConnection { ConnectionString = ConnectionString };
            using var cmd = new OleDbCommand() { Connection = cn };

            cmd.CommandText = 
                "SELECT TOP 1 EmployeeID, FirstName, LastName " +
                "FROM Employees WHERE EmployeeID = @Id";

            cmd.Parameters.Add("@Id", OleDbType.Integer).Value = identifier;
            cn.Open();

            DataTable table = new DataTable();
            table.Load(cmd.ExecuteReader());

            return table;
        }
    }

    public class Employee
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public override string ToString() => $"{FirstName} {LastName}";
    }
}

表单代码

public partial class EmployeeForm : Form
{
    private readonly BindingSource _employeesBindingSource = 
        new BindingSource();

    public EmployeeForm()
    {
        InitializeComponent();

        _employeesBindingSource.DataSource = EmployeesOperations.EmployeesList();
        EmployeesComboBox.DataSource = _employeesBindingSource;

        dataGridView1.DataSource = EmployeesOperations.EmptyDataTable();
    }

    private void GetSingleEmployeeButton_Click(object sender, EventArgs e)
    {
        int id = ((Employee)EmployeesComboBox.SelectedItem).Id;
        DataTable table = ((DataTable)dataGridView1.DataSource);
        
        DataRow result = table.AsEnumerable()
            .FirstOrDefault(row => row.Field<int>("EmployeeID") == id);

        // only add if not already in the data grid view
        if (result == null)
        {
            table.ImportRow(EmployeesOperations.SingleRow(id).Rows[0]);
        }
    }
}

下面的代码现在可以使用文本框搜索数据库并将多行代码输入到 dataGridView 中。 JohnG 在评论中回答了这个问题。在此张贴以供将来参考。

private void searchButton_Click(object sender, EventArgs e)
    {
        conn1.Open();

        //return ID, IMEI, BatchNum, ICCID, IMSI from dataBase
        OleDbCommand cmd1 = new OleDbCommand("Select ID, IMEI, BatchNum, ICCID, IMSI from TBLTest1 where ID=@param1", conn1);
        cmd1.Parameters.AddWithValue("@param1", txtScannedValue.Text);
        OleDbDataReader reader1;
        reader1 = cmd1.ExecuteReader();

        DataTable dt = new DataTable();
        dt.Load(reader1);

        if (dt.Rows.Count > 0)
        {
            if (dataGridView1.DataSource != null) {  
                ((DataTable)dataGridView1.DataSource).ImportRow(dt.Rows[0]);
            } 
            else 
            { 
                dataGridView1.DataSource = dt; 
            }
        }
        else
        {
            MessageBox.Show("No Data Found");
        }

        //reset textBox
        txtScannedValue.Text = "";

        conn1.Close();
    }