如何将值收集到数组中并将集合传递给 C# 中的 datagridview?

Posted

技术标签:

【中文标题】如何将值收集到数组中并将集合传递给 C# 中的 datagridview?【英文标题】:How to collect values into an array and pass the collection to datagridview in C#? 【发布时间】:2019-09-20 21:02:06 【问题描述】:

我正在使用 C# 在 Asp.Net 中开发一个自定义 POS 应用程序,我在 Windows 窗体上有两个 DataGridView。 DataGridView1 显示所有销售额。当用户单击 DataGridView1 中的任何记录时,DataGridView 上选定记录中的某些详细信息(如 ProductName、Quantity、Variation、UnitPrice 和 TotalCost)将传递给 DataGridView2。这是使用 DataGridView2 中的 CurrentCellChanged 事件完成的。

我的问题是我有多个与我试图在 DataGridView2 上显示的每个销售相关的详细信息,但我无法将所选销售的每个详细信息设置为 DataGridView2 的数据源。这是我到目前为止尝试过的代码:

private void DataGridView1_CurrentCellChanged(object sender, EventArgs e)

    try
    
        string saleId = DataGridView1.CurrentRow.Cells[0].Value.ToString();
        DataGridView2.DataSource = SalesClass.SelectedSaleDetails(saleId);
    
    catch (Exception)
    

    

这里,CurrentCellChanged 事件将选定的 SaleId 传递给我的 SalesClass,我在其中查询与此特定 SaleId 相关的销售详细信息,如下所示:

public static DataTable SelectedSaleDetails(string saleId)

    DataTable dt = new DataTable();
    dt = DataAccess.Select(string.Format("select * from vSalesDetails where SaleID = 0", saleId));
    string[] values;

    foreach (DataRow drItem in dt.Rows)
    
        string variation = drItem["ProductVariation"].ToString();


        string productName = drItem["ProductName"].ToString();
        decimal quantity = Convert.ToDecimal(drItem["SaleQuantity"]);
        decimal saleCostLevelC = Convert.ToDecimal(drItem["LevelCCost"]);
        decimal purchaseCostLevelC = Convert.ToDecimal(drItem["LevelCPurchaseCost"]);
        decimal levelBStandard = Convert.ToDecimal(drItem["LevelBStandard"]);
        decimal levelCStandard = Convert.ToDecimal(drItem["LevelCStandard"]);

        decimal parentTotalSalesCost = 0;
        decimal levelATotalSalesCost = 0;
        decimal levelBTotalSalesCost = 0;
        decimal levelCTotalSalesCost = 0;
        decimal salecost = 0;
        decimal unitCost = 0;
        switch (variation)
        
            case "Parent Product":
                decimal soleProductUnitPrice = Convert.ToDecimal(drItem["SoleProductUnitPrice"]);

                salecost = quantity * soleProductUnitPrice;
                unitCost = soleProductUnitPrice;
                break;

            case "Level A":
                decimal levelBSaleCost = levelCStandard * saleCostLevelC;
                decimal levelASaleCost = levelBStandard * levelBSaleCost;

                salecost = quantity * levelASaleCost;
                unitCost = levelASaleCost;
                break;

            case "Level B":
                decimal saleCostLevelB = levelCStandard * saleCostLevelC;
                salecost = quantity * saleCostLevelB;
                unitCost = saleCostLevelB;
                break;

            case "Level C":
                salecost = quantity * saleCostLevelC;
                unitCost = saleCostLevelC;
                break;

            default:
                break;
        

        values = new string[] productName, variation, unitCost.ToString(), quantity.ToString(), salecost.ToString();
    

//  return each of the productName, variation, unitCost and quantity of a selected Sale here. This is going to be assigned as the DataGridView2 DataSource.

我的代码运行良好,我能够在 foreach 循环内的 values 数组中获取所有必需的值。但是,我无法在此处将特定销售的销售详细信息(产品名称、变化、单位成本和数量)传递回 DataGridView2 数据源:

DataGridView2.DataSource = //values returned from SalesClass;

有没有人可以建议我一个更好但更有效的方法,因为我是这里的新手。

【问题讨论】:

【参考方案1】:

您将values 重新分配为foreach 循环中的最后一行。因此,当您退出该循环时,values 只会在dt 中拥有最后一行的数据。

为什么不创建第二个DataTable,将dt 中的数据按摩到第二个DataTable,然后返回?

public static DataTable SelectedSaleDetails(string saleId)

    DataTable dt = new DataTable();
    dt = DataAccess.Select(string.Format("select * from vSalesDetails where SaleID = 0", saleId));

    DataTable result = new DataTable();
    result.Columns.Add("ProductName");
    result.Columns.Add("Variation");
    result.Columns.Add("UnitCost");
    result.Columns.Add("Quantity");
    result.Columns.Add("SaleCost");

    foreach (DataRow drItem in dt.Rows)
    
       // Massage the data like you're doing...
       // And replace the assignment to values with...

       var row = result.NewRow();
       row["ProductName"] = productName;
       row["Variation"] = variation;
       row["UnitCost"] = unitCost.ToString();
       row["Quanity"] = quantity.ToString();
       row["SaleCost"] = saleCost.ToString();
       result.Add(row);
    
    return result;

附带说明一下,您可能希望了解如何更改 DataAccess.Select 以处理参数化查询。现在,您可能有一个SQL Injection Vulnerability。

【讨论】:

它对我有用。感谢您指出这个主要的 SQL 注入漏洞的免费提示。最好也必须为此提供可靠的解决方案。再次感谢您的礼貌建议【参考方案2】:

您查看过DataGridView 的文档吗?看起来您需要在声明 DataGridView1DataGridView2 的同时声明 BindingSource

private BindingSource bindingSource1 = new BindingSource();

然后将代码更改为

string saleId = DataGridView1.CurrentRow.Cells[0].Value.ToString();
bindingSource1.DataSource = SalesClass.SelectedSaleDetails(saleId);   
DataGridView2.DataSource = bindingSource1;

不要从 SalesClass.SelectedSaleDetails 返回 string[] 类型。你想返回你的DataTabledt

【讨论】:

以上是关于如何将值收集到数组中并将集合传递给 C# 中的 datagridview?的主要内容,如果未能解决你的问题,请参考以下文章

从按钮将值传递给视图控制器字典

如何将值传递给另一个视图控制器?

将值从数据库传递到 vue 组件并将其分配给变量

将c#集合序列化为视图中的jquery数组以通过ajax方法传递给控制器

如何将值从组件传递给道具并设置状态

C ++将值传递给函数中的二维字符数组