Расчет суммы - событие CellFormating в Datagridview слишком медленно работает - PullRequest
0 голосов
/ 20 февраля 2019

Я использую dataGridView1_CellFormatting для суммирования каждого моего столбца.Но это делает мое представление данных очень медленным при прокрутке.When особенно когда у меня большой объем данных.

 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(",", ".") + "€" + "   ";

    }

Есть ли более эффективный способ для этого?Пример, чтобы сделать мою сумму только тогда, когда я получу эту ячейку?Или есть ли другое событие или метод для этого?Tried также попробовал это.

 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(",", ".") + "€" + "   ";

    }

Выглядит немного лучше, но все равно медленно, когда я прокручиваю свое представление данных.

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

Вчера я решил проблему с задержкой DataGridView при прокрутке.В .NET есть свойство DoubleBuffered для DataGridView, но по неизвестным причинам оно скрыто.Вы можете включить его путем Reflexion написания метода расширения для DataGridView.

public static class ExtensionMethods
{
    public static void DoubleBuffered(this DataGridView dgv, bool setting)
    {
        Type dgvType = dgv.GetType();
        PropertyInfo pi = dgvType.GetProperty("DoubleBuffered",
            BindingFlags.Instance | BindingFlags.NonPublic);
        pi.SetValue(dgv, setting, null);
    }
}

. Поместите этот код где-нибудь в вашем проекте и после инициализации формы установите для свойства DoubleBuffered значение true:

dataGridView1.DoubleBuffered(true);

Мне очень помогло исполнение DataGridView.Надеюсь, это поможет вам.

0 голосов
/ 20 февраля 2019

Это уже упоминалось в документации :

Событие CellFormatting происходит каждый раз, когда каждая ячейка окрашивается, поэтому при обработке этого события следует избегать длительной обработки.Это событие также происходит, когда извлекается ячейка FormattedValue или вызывается ее метод GetFormattedValue.

Обработка CellFormatting для всех ячеек слишком велика для вычисления Sum.

Если вы используете DataSource подобно DataTable, которое вызывает событие ListChanged, для вычисления Sum вы можете положиться на событие ListChanged.

В качестве другого вариантаможно рассчитывать на RowsAdded, RowsRemoved и CellValueChanged событие DataGridView для вычисления Sum.

Пример - DataTable - сумма столбца

DataTable вызывает ListChange событие.Вы можете подписаться на событие для обновления текстового поля:

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}";
}

Пример - Список - Сумма свойства

List<T> неподнять ListChanged событие.Вы можете использовать BindingSource в качестве источника данных и обрабатывать ListChanged событие BindingSource вместо:

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}";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...