【问题标题】:datagridview cells multiplying and sum the column in textboxdatagridview 单元格相乘并求和文本框中的列
【发布时间】:2021-07-06 11:28:41
【问题描述】:

在datagridview中相乘并在C#的文本框中显示最终结果后,我在将一行的两个单元格相乘并对一列求和时遇到问题,请指导我如何做到这一点enter image description here

  private void btnsum_Click(object sender, EventArgs e)
        { 
            int multiplication  = 0;           
            int sum  = 0;
         
            for (int i = 0; i < saleDataGridView.Rows.Count; i++)
            {
                if (saleDataGridView != null)
                {
                    if (int.TryParse(saleDataGridView.Rows[i].Cells[1].Value.ToString(), out sum) && int.TryParse(saleDataGridView.Rows[i].Cells[6].Value.ToString(), out multiplication))
                    {
                        int total = sum * multiplication + Convert.ToInt32(saleDataGridView.Rows[i].Cells[1].Value);



                        // sum += *Convert.ToInt32(saleDataGridView.Rows[i].Cells[6].Value);



                        txttotal.Text = total.ToString();
                    }
                    else {

                        MessageBox.Show("error");

                    }

enter image description here

【问题讨论】:

  • 你使用的是winforms还是wpf?
  • 我正在使用 winforms
  • 你能详细解释一下你的问题吗
  • 我在我的 saledatagridview 中有两个列,一个数量,另一个是价格,我想在每行中的多个数量和价格列乘以我想对价格列求和并通过按钮单击在文本框中显示结果。

标签: c# datagridview sum row


【解决方案1】:

我认为使用泛型 List 绑定 DataGridView 很容易。

例如

class MyModel
{
    public double Price { get; set; }
    public double Quantity { get; set; }
}

将此模型绑定到 DataGridView 并使用 LINQ 计算总数,单击按钮示例后:

public partial class Form1 : Form
    {
        private List<MyModel> myData;
        public Form1()
        {
            InitializeComponent();
            myData = new List<MyModel>() { new MyModel() {Price=35000,Quantity=100 }, new MyModel() { Price = 150000, Quantity = 322 } };
            dataGridView1.DataSource = myData;
        }        

        private void btnCalc_Click(object sender, System.EventArgs e)
        {
            var result = myData.Sum(s => s.Price * s.Quantity);
            txtBoxTotal.Text = result.ToString();
        }
    }

结果:

其他解决方案,如果您想使用 DataGridView Cells 进行计算:

double result = 0;
foreach (DataGridViewRow row in dataGridView1.Rows)
{

 var price = double.Parse(row.Cells[0].Value.ToString());
 var quantity = double.Parse(row.Cells[1].Value.ToString());
 result += price * quantity;
}
txtBoxTotal.Text = result.ToString();

对于您的情况:

private void btnsum_Click(object sender, EventArgs e)
{
   var result = 0;
   foreach (DataGridViewRow row in saleDataGridView.Rows)
    {
       int price, quantity;
       if (int.TryParse(row.Cells[1].Value.ToString(), out price) && int.TryParse(row.Cells[6].Value.ToString(), out quantity))
          result += price * quantity;
             else
                  MessageBox.Show("error");
      }
 txttotal.Text = result.ToString();
}

【讨论】:

    【解决方案2】:

    有很多方法可以解决这个问题。显然,您可以遍历网格行并计算每行的总数并将所有这些值相加。或者,如果网格有数据源,您可以遍历这些行/项目并获取总数。

    因此,由于您没有说明网格是否具有数据源,因此很难提出适当的解决方案。例如,如果网格的基础数据源是DataTable,那么您可以将“总计”“表达式”列“添加”到网格中,以计算每行的“价格”*“数量”值。这将从您的代码中删除一项计算。您还可以使用DataTableCompute 函数将文本框文本设置为DataTable 中所有“总计”单元格的总和,从而消除您必须编写的另一个计算。每当网格“价格”或“数量”值发生变化时,我们将使用数据表 Compute 函数更新文本框总和。

    或者正如 Mansur 的回答所暗示的,您可以创建一个简单的类来管理网格的数据源以及文本框数据绑定。这是下面使用的方法。在Item 类中,将有三个属性,其中“价格”和“数量”都是“可编辑”属性。第三个属性将是一个只读的“Total”,它将返回“Price”*“Quantity”值。

    我们可以简单地创建一个Item 对象的列表,它应该会让事情变得更容易,但是,我说让我们更进一步,创建另一个名为ListOfItems 的类,它将有两个属性。一个BindingListItem 对象和一个decimal 只读属性,它返回列表中所有项目的SumTotal

    这个类的想法是我们现在可以将网格和TextBox 绑定到“相同的”DataSource。网格的DataMember 将是Item 对象的BindingList,为了绑定TextBox,我们将其DataMember 设置为SumTotal 属性。就计算每行总数和所有行的总数而言,这应该会使事情变得更容易。

    public class Item {
      public decimal Price { get; set; }
      public int Quantity { get; set; }
      public decimal Total => Price * Quantity;
    }
    
    
    public class ListOfItems {
      public BindingList<Item> Items { get; set; }
    
      public ListOfItems() {
        Items = new BindingList<Item>();
      }
    
      public decimal SumTotal => Items.Sum(x => x.Total);
    }
    

    但是,有一个小问题。如果我们查看ListOfItems 类......我们可以看到SumTotal 将反映Items 列表的当前状态,但是如果列表发生变化,那么我们仍然需要一些机制来向文本框发出信号以“更新“ 总数。此外,当用户更改网格单元格值时,在某些情况下,网格中的数据可能不一定存在于底层数据源中。在这种情况下,总数可能是错误的。

    如果我们简单地使用BindingSource,这些问题(以及其他问题)可以得到解决。如果我们使用BindingSource 并将它的DataSource 设置为ListOfItems 对象,那么当单元格价格或数量发生变化时,我们需要做的就是调用BindingSourceResetBinding 方法,它应该会更新网格和文本框一步到位。即使这不是必需的,在网格中使用 BindingSource 也有很多优点……就像这样。

    要对此进行测试,您可以创建一个新的 winforms 解决方案,并将一个 DataGridView 和一个 TextBox 放在表单上以表示总和。有两个全局变量……BindingSourceListOfItems 对象。下面的代码是用来生成一些测试数据的。

    private ListOfItems GetData() {
      ListOfItems listOfItems = new ListOfItems();
      listOfItems.Items.Add(new Item { Price = 10.50m, Quantity = 2 });
      listOfItems.Items.Add(new Item { Price = 1.0m, Quantity = 3 });
      listOfItems.Items.Add(new Item { Price = 1.50m, Quantity = 3 });
      return listOfItems;
    }
    

    设置一切的加载方法……

    BindingSource bs;
    ListOfItems AllItems;
    
    public Form1() {
      InitializeComponent();
      dataGridView1.CellValueChanged += new DataGridViewCellEventHandler(dataGridView1_CellValueChanged);
    }
    
    private void Form1_Load(object sender, EventArgs e) {
      AllItems = GetData();
      bs = new BindingSource();
      bs.DataSource = AllItems;
      dataGridView1.DataSource = bs;
      dataGridView1.DataMember = "Items";
      textBox1.DataBindings.Add("Text", bs, "SumTotal");
    }
    

    最后,网格CellValueChanged 事件在“价格”或“数量”单元格更改时更新文本框。我们需要做的就是重置要更新的文本框的绑定源。

    private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) {
      if (dataGridView1.Columns[e.ColumnIndex].Name == "Price" ||
          dataGridView1.Columns[e.ColumnIndex].Name == "Quantity") {
        if (dataGridView1.Rows[e.RowIndex].Cells["Price"].Value != null &&
            dataGridView1.CurrentRow.Cells["Quantity"].Value != null) {
          if (!string.IsNullOrWhiteSpace(dataGridView1.CurrentRow.Cells["Price"].FormattedValue.ToString()) &&
              !string.IsNullOrWhiteSpace(dataGridView1.CurrentRow.Cells["Quantity"].FormattedValue.ToString())) {
            bs.ResetBindings(false);
          }
        }
      }
    }
    

    最后,如前所述,您可以使用DataTable 执行相同的操作,方法是将ListOfItems 类的Items 属性更改为DataTable,并使用LINQ 或DataTable 的@ 987654367@ 函数计算总和。在我的测试中,这将需要额外的步骤,但这很简单。

    我希望这是有道理的。

    【讨论】:

      【解决方案3】:
      private void button1_Click(object sender, EventArgs e) {      
          int sum = 0;
          for (int i = 0; i < dataGridView1.Rows.Count; i++) {
              sum += Convert.ToInt32(dataGridView1.Rows[i].Cells[4].Value);
          }
          txtTotal.Text = sum.ToString();
      }
      

      【讨论】:

      • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-01
      • 1970-01-01
      相关资源
      最近更新 更多