Darkenor
Darkenor

Reputation: 4449

CellFormatting event causing rendering shakiness on .NET 4.5 application

In a simple .NET WinForm I have a datagridview that is being color painted based on the value of cells. The code is working, but the rendered form is "shaky" (that look when a computer is constantly having to redraw and can't keep up). I am wondering if there's something I can do to eliminate this, or if there's something wrong with my code. Advice appreciated.

private void gvPhoneQueue_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            try
            {
                if (gvPhoneQueue.Columns[e.ColumnIndex].HeaderText == "CallsWaiting")
                {
                    string convertedVal = e.Value.ToString();
                    if (Convert.ToInt32(convertedVal) > _greenTolerance)
                    {
                        gvPhoneQueue.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Green;
                    }

                    if (Convert.ToInt32(convertedVal) > _yellowTolerance)
                    {
                        gvPhoneQueue.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Yellow;
                    }

                    if (Convert.ToInt32(convertedVal) > _redTolerance)
                    {
                        gvPhoneQueue.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Red;
                    }
                }
            }
            catch (System.Exception ex)
            {
                LogEvent("Error" _+ ex);
            }
        }

Upvotes: 2

Views: 253

Answers (1)

Chris
Chris

Reputation: 8647

I have already seen some threads about performance issue of DataGridView in such case (using CellFormatting, CellPainting, ...). This could be a "known issue" when working with a lot a data.

What is sure, you should avoid to do something too much complicated in CellFormating event. I don't see something wrong in your code, but it doesn't seem to be optimized:

  • You use 3 times Convert.ToInt32(convertedVal) : you should store the value instead of convert 3 times the string value. And if you are using a Try Cath block, due to possible converting error, you could use instead the int32.TryParse method.

  • I guess the color can't be both red, yellow, or green, and _redTolerence is the highest value? So you should start by testing the highest value and then others, and so exit from the method as soon as you can and so do not evaluate the 3 if statements each time if not needed. In VB.Net I would recommend to use ElseIf statement but it does not exist in C#.Using return would be the same in this case. [EDIT My mistake else if in C# equals ElseIf in VB.Net].


Possible optimization:

private void gvPhoneQueue_CellFormatting(object sender, System.Windows.Forms.DataGridViewCellFormattingEventArgs e)
{
    if (gvPhoneQueue.Columns(e.ColumnIndex).HeaderText == "CallsWaiting") {
        int convertVal = 0;
        if (int.TryParse(e.Value.ToString, convertVal)) {
            if (convertVal > _redTolerance) {
                gvPhoneQueue.Rows(e.RowIndex).DefaultCellStyle.BackColor = Color.Red;
            } else if (convertVal > _yellowTolerance) {
                gvPhoneQueue.Rows(e.RowIndex).DefaultCellStyle.BackColor = Color.Yellow;
            } else if (convertVal > _greenTolerance) {
                gvPhoneQueue.Rows(e.RowIndex).DefaultCellStyle.BackColor = Color.Green;
            }
        } else {
            //can't convert e.value
        }
    }
}

Upvotes: 2

Related Questions