计算总和-Datagridview的CellFormating事件性能太慢 [英] Calculating Sum - Datagridview's CellFormating event too slow performance
问题描述
我正在使用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 $ c $的
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屋!