数据绑定DataGridView错误显示文本框的文本

时间:2014-03-29 23:32:17

标签: c# datagridview

我有一个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); }

提前致谢

2 个答案:

答案 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处理您的SqlConnectionSqlDataAdapter

我假设您要将文字用作%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控件中向用户显示所有这些信息。

以下是我的建议:

  1. prdctName条款中包含SELECT字段。
  2. 如果您想将所有相关数据绑定到包含DataGridView变量和Quantity计算的TotalPrice,请将其包含在SELECT语句中。当您从这样的SQL查询将数据绑定到控件时,结果集将映射到网格。换句话说,如果您希望在设置DataSource属性时显示信息,则需要在SQL结果集中包含该信息。
  3. 请勿使用LIKEprdctName进行比较,因为它会略微模糊查询的目的,而只是使用=运算符。
  4. 此外,从表格设计的角度来看,我会在UNIQUE INDEX列中添加prdctName,如果它在您的表格中确实是唯一的 - 我感觉可能就是这样。这将改善您正在使用的查询的性能。
  5. 以下是您的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);
    

    enter image description here