计算总和-Datagridview的CellFormating事件性能太慢 [英] Calculating Sum - Datagridview's CellFormating event too slow performance

查看:155
本文介绍了计算总和-Datagridview的CellFormating事件性能太慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用dataGridView1_CellFormatting对每个列求和。但这使我的datagridview滚动非常慢。特别是当我有大量数据时。
$ b小数和= 0,sum2 = 0,sum3 = 0;
for(int i = 0; i< CustomersGrid.Rows.Count; ++ i)
{

sum + = Convert.ToDecimal(CustomersGrid.Rows [e。 RowIndex] .Cells [7] .Value);
sum2 + = Convert.ToDecimal(CustomersGrid.Rows [e.RowIndex] .Cells [6] .Value);
sum3 + = Convert.ToDecimal(CustomersGrid.Rows [e.RowIndex] .Cells [8] .Value);
}

Quantitytxt.Text = sum2.ToString()+;
Sumtxt.Text = string.Format( {0:0.00},sum).Replace(,,。)+€ +;
DiscountSumtxt.Text = string.Format( {0:0.00},sum3).Replace(,,。)+€ +;

}

还有其他更有效的方法吗?仅当我将获得此单元格时才求和的示例?或者,是否还有其他事件或方法呢?

  private void dataGridView1_CellFormatting(对象发送者,DataGridViewCellFormattingEventArgs e)
{

小数和= 0,sum2 = 0,sum3 = 0;
for(int i = 0; i< CustomersGrid.Rows.Count; ++ i)
{
if(e.ColumnIndex == 7 || e.ColumnIndex == 6 | | e.ColumnIndex == 8)
{
sum + = Convert.ToDecimal(CustomersGrid.Rows [e.RowIndex] .Cells [7] .Value);
sum2 + = Convert.ToDecimal(CustomersGrid.Rows [e.RowIndex] .Cells [6] .Value);
sum3 + = Convert.ToDecimal(CustomersGrid.Rows [e.RowIndex] .Cells [8] .Value);
}
}
Quantitytxt.Text = sum2.ToString()+;
Sumtxt.Text = string.Format( {0:0.00},sum).Replace(,,。)+€ +;
DiscountSumtxt.Text = string.Format( {0:0.00},sum3).Replace(,,。)+€ +;

}

性能似乎略好,但在我正在滚动我的datagridview。

解决方案

文档


每次绘制每个单元格都会发生CellFormatting事件,因此
在处理此事件时应避免冗长的处理。当检索单元格FormattedValue或调用其
GetFormattedValue方法时,也会发生此
事件。


处理 CellFormatting 对于所有单元格来说对于计算 Sum 而言实在太多了。



如果您使用的是 DataSource 之类的 DataTable 引发 ListChanged 事件,要计算 Sum ,您可以依靠 ListChanged 事件。



作为另一种选择,您可以依靠 Row☎联系人 RowsRemoved DataGridView CellValueChanged 事件来计算 Sum



示例-数据表-列的总和



DataTable 引发 ListChange 事件。您可以订阅事件以更新文本框:

 私有异步void Form1_Load(对象发送者,EventArgs e)
{
//定义数据表
var dt = new DataTable();
dt.Columns.Add( Name);
dt.Columns.Add( Price,typeof(int));

//填充数据
dt.Rows.Add(产品1,100);
dt.Rows.Add(产品2,200);

//设置数据网格视图的数据源
this.dataGridView1.DataSource = dt;

//通过价格的总和自动更新文本框
textBox1.Text = $ {dt.Compute( SUM(Price),):F2};
dt.DefaultView.ListChanged + =(obj,args)=>
textBox1.Text = $ {dt.Compute( SUM(Price),):F2};
}

示例-列表< T> -财产总和



List< T> 不会产生 ListChanged 事件。您可以使用 BindingSource 作为数据源,并处理 BindingSource ListChanged 事件。 c>代替:

 公共类产品
{
公共字符串名称{get;组; }
public int Price {get;组; }
}

私有异步void Form1_Load(对象发送者,EventArgs e)
{
//定义列表
var list = new List< Product> ();

//填充数据
list.Add(新产品{名称=产品1,价格= 100});
list.Add(新产品{名称=产品2,价格= 200});

//设置数据网格视图的数据源
var bs = new BindingSource();
bs.DataSource =列表;
this.dataGridView1.DataSource = bs;

//通过价格
的总和自动更新文本框textBox1.Text = $ {list.Sum(x => x.Price):F2};
bs.ListChanged + =(obj,args)=>
textBox1.Text = $ {list.Sum(x => x.Price):F2};
}


I am using dataGridView1_CellFormatting for making sum to each my column. But this makes my datagridview very slow on scrolling. Εspecially when i have big amount of data.

 private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
    {

        Decimal sum = 0, sum2 = 0, sum3 = 0;
        for (int i = 0; i < CustomersGrid.Rows.Count; ++i)
        {

                sum += Convert.ToDecimal(CustomersGrid.Rows[e.RowIndex].Cells[7].Value);
                sum2 += Convert.ToDecimal(CustomersGrid.Rows[e.RowIndex].Cells[6].Value);
                sum3 += Convert.ToDecimal(CustomersGrid.Rows[e.RowIndex].Cells[8].Value);
        }

        Quantitytxt.Text = sum2.ToString() + "   ";
        Sumtxt.Text = string.Format("{0:0.00}", sum).Replace(",", ".") + "€" + "   ";
        DiscountSumtxt.Text = string.Format("{0:0.00}", sum3).Replace(",", ".") + "€" + "   ";

    }

Is there any more effective way for this? Example to make my sum only when i will get this cell? Or if there is any other event or method for this? Ι also tried this.

 private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
    {

        Decimal sum = 0, sum2 = 0, sum3 = 0;
        for (int i = 0; i < CustomersGrid.Rows.Count; ++i)
        {
            if (e.ColumnIndex == 7 || e.ColumnIndex == 6 || e.ColumnIndex == 8)
            {
                sum += Convert.ToDecimal(CustomersGrid.Rows[e.RowIndex].Cells[7].Value);
                sum2 += Convert.ToDecimal(CustomersGrid.Rows[e.RowIndex].Cells[6].Value);
                sum3 += Convert.ToDecimal(CustomersGrid.Rows[e.RowIndex].Cells[8].Value);
            }
        }
        Quantitytxt.Text = sum2.ToString() + "   ";
        Sumtxt.Text = string.Format("{0:0.00}", sum).Replace(",", ".") + "€" + "   ";
        DiscountSumtxt.Text = string.Format("{0:0.00}", sum3).Replace(",", ".") + "€" + "   ";

    }

It looks little better performance, but it still is slow when i am scrolling my datagridview.

解决方案

It's already mentioned in the documentations:

The CellFormatting event occurs every time each cell is painted, so you should avoid lengthy processing when handling this event. This event also occurs when the cell FormattedValue is retrieved or its GetFormattedValue method is called.

Handling CellFormatting for all cells is too much for calculating Sum.

If you are using a DataSource like DataTable which raises ListChanged event, to calculate the Sum, you can rely on ListChanged event.

As another option, you can rely on RowsAdded, RowsRemoved and CellValueChanged event of DataGridView to calculate the Sum.

Example - DataTable - Sum of a Column

DataTable raises ListChange event. You can subscribe to the event for updating the text box:

private async void Form1_Load(object sender, EventArgs e)
{
    // Define data table
    var dt = new DataTable();
    dt.Columns.Add("Name");
    dt.Columns.Add("Price", typeof(int));

    // Fill data
    dt.Rows.Add("Product 1", 100);
    dt.Rows.Add("Product 2", 200);

    // Set data source of data grid view
    this.dataGridView1.DataSource = dt;

    // Automatically update text box, by SUM of price
    textBox1.Text = $"{dt.Compute("SUM(Price)", ""):F2}";
    dt.DefaultView.ListChanged += (obj, args) =>
        textBox1.Text = $"{dt.Compute("SUM(Price)", ""):F2}";
}

Example - List<T> - Sum of a Property

List<T> doesn't raise ListChanged event. You can use BindingSource as data source and handle ListChanged event of BindingSource instead:

public class Product
{
    public string Name { get; set; }
    public int Price { get; set; }
}

private async void Form1_Load(object sender, EventArgs e)
{
    // Define list
    var list = new List<Product>();

    // Fill data
    list.Add(new Product { Name = "Product 1", Price = 100 });
    list.Add(new Product { Name = "Product 2", Price = 200 });

    // Set data source of data grid view
    var bs = new BindingSource();
    bs.DataSource = list;
    this.dataGridView1.DataSource = bs;

    // Automatically update text box, by SUM of price
    textBox1.Text = $"{list.Sum(x => x.Price):F2}";
    bs.ListChanged += (obj, args) =>
        textBox1.Text = $"{list.Sum(x => x.Price):F2}";
}

这篇关于计算总和-Datagridview的CellFormating事件性能太慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆