如何从文本框搜索中向 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();
}
我正在使用以下代码在 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();
}