如何在第二个 gridview 中显示信息

How to show info in second gridview

我使用 Nordwind 数据库

这是我的应用程序的外观:

我想 select 第一个网格视图中的一行,并在第二个网格视图中显示这些客户的订单我还想在第一个网格视图中过滤 1 个或多个列。

网格视图 1:

private void Form1_Load(object sender, EventArgs e)
{
    SqlConnection conn = new SqlConnection(@"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Northwind.mdf;Integrated Security=True");conn.Open();

    SqlCommand cmd = new SqlCommand("select * from Customers", conn);

    SqlDataReader rdr = cmd.ExecuteReader();

    List<Customer> Customers = new List<Customer>();

    while (rdr.Read())
    {
        Customer c = new Customer();
        c.CustomerID = (string)rdr["CustomerID"];
        c.CompanyName = (string)rdr["CompanyName"];
        c.ContactName = (string)rdr["ContactName"];
        c.City = (string)rdr["City"];
        c.Country = (string)rdr["Country"];
        c.Phone = (string)rdr["Phone"];
        Customers.Add(c);
    }

    dataGridView1.DataSource = Customers;
}

GridView2:

private void dataGridView2_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    SqlConnection conn = new SqlConnection(@"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Northwind.mdf;Integrated Security=True"); 
    conn.Open();

    SqlCommand cmd = new SqlCommand("select * from Orders", conn);

    SqlDataReader rdr = cmd.ExecuteReader();

    List<Order> Orders = new List<Order>();

    while (rdr.Read())
    {
        Order o = new Order();
        o.OrderID = (int)rdr["OrderID"];
        o.OrderDate = (DateTime)rdr["OrderDate"];
        o.ShipName = (string)rdr["ShipName"];
        o.ShipCity = (string)rdr["ShipCity"];
        o.ShipCountry = (string)rdr["ShipCountry"];
        Orders.Add(o);
    }

    dataGridView2.DataSource = Orders;
}

Select整行:

        {
            Customer c = (Customer)dataGridView1.CurrentRow.DataBoundItem;
        }

我认为 SqlCommand 在 GridView2 中不太好,我认为我需要更新表单,但我不知道该怎么做。

有人可以给我正确的代码,甚至可以解释一下哪个部分做什么吗?

提前致谢如果您需要更多信息,请说出来。

不要在 CellContentClick 中执行此操作,而是在 SelectionChanged 事件处理程序中执行此操作。订单必须有一个 CustomerID 可以用来在 WHERE 子句中过滤:

private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
    if (dataGridView1.CurrentRow?.DataBoundItem is Customer customer) {
        var orders = new List<Order>();

        using (var conn = new SqlConnection(STR_Connection))
        using (var cmd = new SqlCommand("select * from Orders where CustomerID=@cid", conn)) {
            cmd.Parameters.Add("@cid", SqlDbType.NChar, 5).Value = customer.CustomerID;

            conn.Open();
            using (SqlDataReader rdr = cmd.ExecuteReader()) {
                while (rdr.Read()) {
                    var o = new Order {
                        OrderID = (int)rdr["OrderID"],
                        CustomerID = (string)rdr["CustomerID"],
                        OrderDate = (DateTime)rdr["OrderDate"],
                        ShipName = (string)rdr["ShipName"],
                        ShipCity = (string)rdr["ShipCity"],
                        ShipCountry = (string)rdr["ShipCountry"]
                    };
                    orders.Add(o);
                }
            }
        }

        dataGridView2.DataSource = orders;
    } else {
        dataGridView2.DataSource = null;
    }
}

将参数作为命令参数传递并将其连接成 SQL 命令字符串很重要。这可能会导致 SQL 注入攻击(这里可能不会,但在一般情况下......)。它还提高了查询的性能,因为 SQL-Server 可以缓存执行计划,因为命令字符串不会因不同的客户而改变。

将连接、命令和 reader 放在 using 语句中以自动处理它们。


通过文本框进行过滤的方式非常相似。在文本框的 TextChangedValidatedLeave 事件中重新加载客户:

private void txtFilter_TextChanged(object sender, EventArgs e)
{
    LoadCustomers(txtFilter.Text);
}

并且在 Load 事件中:

private void Form1_Load(object sender, EventArgs e)
{
    LoadCustomers();
}

TextChanged 与其他两个事件的区别在于前者会在输入每个字符时触发。要让其他人工作,您必须离开文本框。

那么你将不得不处理过滤器是否为空的两种情况。如果为空,则 select 没有 WHERE 子句的客户(即 return 所有行)或根本没有 return 行(dataGridView1.DataSource = null;)。否则设置适当的 where 子句。也许

WHERE CompanyName LIKE @filter OR ContactName LIKE @filter

然后在 % 中嵌入过滤字符串。这是SQL.

中的通配符
private void LoadCustomers(string filter = null) // Optional filter parameter
{
    string sql = "select * from Customers";
    SqlParameter filterParameter = null;
    if (!String.IsNullOrWhiteSpace(filter)) {
        sql += " WHERE CompanyName LIKE @filter OR ContactName LIKE @filter";
        filterParameter = new SqlParameter("@filter", SqlDbType.NVarChar) {
            Value = "%" + filter + "%" // Add wildcards.
        };
    }

    var Customers = new List<Customer>();
    using (var conn = new SqlConnection(STR_Connection))
    using (var cmd = new SqlCommand(sql, conn)) {
        if (filterParameter != null) {
            cmd.Parameters.Add(filterParameter);
        }
        conn.Open();
        using (var rdr = cmd.ExecuteReader()) {
            while (rdr.Read()) {
                var c = new Customer() {
                    CustomerID = (string)rdr["CustomerID"],
                    CompanyName = (string)rdr["CompanyName"],
                    ContactName = (string)rdr["ContactName"],
                    City = (string)rdr["City"],
                    Country = (string)rdr["Country"],
                    Phone = (string)rdr["Phone"]
                };
                Customers.Add(c);
            }
        }
    }
    dataGridView1.DataSource = Customers;
}