C# 数据绑定DataGridView显示文本框的文本出错

C# 数据绑定DataGridView显示文本框的文本出错,c#,datagridview,C#,Datagridview,我有一个datagridview DGVSelectEditeRemand,我希望它显示文本框中的一些值,但我有这个错误 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;da

我有一个datagridview DGVSelectEditeRemand,我希望它显示文本框中的一些值,但我有这个错误

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); }

提前感谢

我在internet上搜索过,当您设置DataGridView的属性时,似乎无法通过编程方式添加新行

最常见的方法是将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中的第二个参数传递是一种更好的方法

你应该经常使用。这种类型的字符串连接对攻击是开放的

最后,不要忘记使用来处理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;
   }
}
按操作更新评论

因此,您希望用户输入产品名称和数量,然后对数据库运行查询以检索单价信息。然后,您希望在DataGridView控件中向用户显示所有这些信息

以下是我的建议:

在SELECT子句中包含prdctName字段。 如果要将所有相关数据绑定到DataGridView,包括Quantity变量和TotalPrice计算,请将它们包含在SELECT语句中。当您从这样的SQL查询将数据绑定到控件时,结果集将映射到网格。换句话说,如果希望在设置DataSource属性时显示信息,则需要在SQL结果集中包含该信息。 不要对prdctName使用LIKE to compare,因为它会稍微模糊查询的目的,而只使用=运算符。 此外,从表设计的角度来看,如果prdctName列在您的表中确实是唯一的,我会在prdctName列上添加一个唯一的索引,我感觉它很可能是唯一的。这将提高您正在使用的查询的性能。 下面是您的SQL现在应该是什么样子:

SELECT prdctName, UnitPrice, @Quantity AS Quantity, 
       UnitPrice * @Quantity AS Total_Price 
FROM ProductDetails
WHERE prdctName = @prdctName
其他一些建议是使用准备好的SQL语句和.NET的using语句,正如Soner Gönül所指出的那样。我会尽力给你运用这些技巧的动力

为什么要使用准备好的SQL语句

当准备好的语句或参数化查询被编译和优化一次时,您可以获得安全性和性能提升

为什么要在.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);

数据行dr=dt.NewRow;dt.Rows.Adddr;事实上我做了,但错误仍然出现在这里,或者你真的想添加一列?这是可行的。事实上,它不起作用。可能只是我,但我不太确定你在问什么。您不能分配数据源并以编程方式添加行。因此,如果有其他方法可以满足我的需要,请允许我非常感兴趣。我只是假设OP的意思是使用LIKE而不使用任何通配符。查询优化器可能会将其简化为A=。我希望用户在文本框中写入产品的名称和数量,并根据这些数据将其显示在datagridview中所选产品的价格将从数据库中显示,我尝试了所有这些解决方案,但都不起作用,我还尝试使用数组向datgridview添加行,但没有意义too@DerekWOP想要什么还不完全清楚。这就是为什么我在%%之间使用它。但它当然可以很容易地改变。@SonerGönül:是的,我不是想说它是批评。我只是在评论一些歧义如何导致不同的解释。感谢您的帮助,我使用了BindData方法:BindDataTXSelectedName.Text,Convert.ToInt32TXSelectedQNty.Text;但是什么都没有发生,没有错误,没有结果,而不是单价,所以只有单价列出现了?AutoGenerateColumns属性是否设置为false?您是否可以逐步查看代码,并查看DataTable对象在调用Fill后有多少列?如何设置?我不明白你是否在使用VS这里有一个指南: