我有一个datagridview(dgvSelectedItem),我希望它显示文本框中的一些值,但我有这个错误
Rows cannot be programmatically added to the DataGridView's rows collection when the control is data-bound
我的代码是:
DataTable dt = new DataTable();
string conn = "server=.;uid=sa;pwd=123;database=PharmacyDB;";
Okbtn()
{
SqlDataAdapter da = new SqlDataAdapter("select UnitPrice from ProductDetails where prdctName like '"+txtSelectedName.Text + "'", conn);
da.Fill(dt);
dgvSelectedItem.DataSource = dt;
//this code work but when I add these lines the Error appear
dgvSelectedItem.Rows.Add(txtSelectedName.Text);
dgvSelectedItem.Rows.Add(txtSelectedQnty.Text); }
提前致谢
答案 0 :(得分:0)
我在互联网上搜索,看起来在设置DataGridView
的{{3}}属性时,无法以编程方式添加新行。
最常见的方法是添加DataTable
这些值,然后将其绑定到DataSource
属性,如:
da.Fill(dt);
DataRow dr = dt.NewRow();
dr["UnitPrice"] = txtSelectedName.Text;
dt.Rows.Add(dr);
dt.Rows.Add(dr);
dgvSelectedItem.DataSource = dt;
此外,conn
是您的连接字符串,而不是SqlConnection
。在我看来,将SqlConnection
作为SqlDataAdapter
中的第二个参数传递是一种更好的方法。
您应始终使用DataSource
。这种字符串连接对parameterized queries攻击开放。
最后,请勿忘记使用SQL Injection处理您的SqlConnection
和SqlDataAdapter
。
我假设您要将文字用作%txtSelectedName.Text%
,这是我的例子;
DataTable dt = new DataTable();
using(SqlConnection conn = new SqlConnection("server=.;uid=sa;pwd=123;database=PharmacyDB;"))
using(SqlCommand cmd = new SqlCommand("select UnitPrice from ProductDetails where prdctName like @param"))
{
cmd.Connection = conn;
cmd.Parameter.AddWithValue("@param", "%" + txtSelectedName.Text + "%");
using(SqlDataAdapter da = new SqlDataAdapter(cmd, conn))
{
da.Fill(dt);
DataRow dr = dt.NewRow();
dr["UnitPrice"] = txtSelectedName.Text;
dt.Rows.Add(dr);
dt.Rows.Add(dr);
dgvSelectedItem.DataSource = dt;
}
}
答案 1 :(得分:0)
根据OP评论更新
因此,您希望用户输入产品名称和数量,然后对数据库运行查询以检索单价信息。然后,您希望在DataGridView
控件中向用户显示所有这些信息。
以下是我的建议:
prdctName
条款中包含SELECT
字段。DataGridView
变量和Quantity
计算的TotalPrice
,请将其包含在SELECT
语句中。当您从这样的SQL查询将数据绑定到控件时,结果集将映射到网格。换句话说,如果您希望在设置DataSource
属性时显示信息,则需要在SQL结果集中包含该信息。 LIKE
对prdctName
进行比较,因为它会略微模糊查询的目的,而只是使用=
运算符。UNIQUE INDEX
列中添加prdctName
,如果它在您的表格中确实是唯一的 - 我感觉可能就是这样。这将改善您正在使用的查询的性能。 以下是您的SQL现在的样子:
SELECT prdctName, UnitPrice, @Quantity AS Quantity,
UnitPrice * @Quantity AS Total_Price
FROM ProductDetails
WHERE prdctName = @prdctName
其他一些建议是使用准备好的SQL语句和.NET的using
语句,如SonerGönül所述。我会尽力给你应用这些技巧的动力。
为什么要使用准备好的SQL语句?
您可以获得SQL Injection attacks的安全性和性能提升,因为准备好的语句(也就是参数化查询)会被编译和优化一次。
为什么我要在.NET中使用using
语句?
确保在相关对象上调用Dispose()
方法。这将释放对象消耗的非托管资源。
我写了一个小测试方法,例证了所有这些:
private void BindData(string productName, int quantity)
{
var dataTable = new DataTable();
string sql = "SELECT prdctName, UnitPrice, @Quantity AS Quantity, " +
"UnitPrice * @Quantity AS Total_Price " +
"FROM ProductDetails " +
"WHERE prdctName = @prdctName";
using (var conn = new SqlConnection(connectionString))
{
using (var cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("@prdctName", productName);
cmd.Parameters.AddWithValue("@Quantity", quantity);
using (var adapter = new SqlDataAdapter(cmd))
{
adapter.Fill(dataTable);
dataGridView1.DataSource = dataTable;
}
}
}
}
以下是此方法的示例输入和输出:
BindData("Lemon Bars", 3);