Question

I have a problem with my code at event Paint. My form very lag because too many for loop in Paint + Paint is always redraw and loop my for loop in event Paint. whether it can draw on paint event only one time and does not redraw anymore?

This the image : MyImage This is my code

Rectangle r1;
    Rectangle r2;
    Rectangle r3;
    int w2 = 0;
    private void dataGridView1_Paint(object sender, PaintEventArgs e)
    {
        ///
        /// Menggambar Header Column menjadi terlihat seperti di merge cells
        ///
        base.AutoScroll = true;
        int h = 0;
        for (int j = 0; j < myKaryawan.CountKaryawan() * 2; )
        {
            newImage = imglists[h];
            Rectangle recBackground = this.dataGridView1.GetCellDisplayRectangle(j, -1, true);
            Rectangle recImage = this.dataGridView1.GetCellDisplayRectangle(j, -1, true);
            Rectangle recString = this.dataGridView1.GetCellDisplayRectangle(j, -1, true);
            w2 = this.dataGridView1.GetCellDisplayRectangle(j + 1, -1, true).Width;
            recBackground.X += 1;
            recBackground.Y += 1;
            recImage.X += 1;
            recImage.Y += 1;
            recString.X += (recString.Width + w2) / 2;
            recString.Y += 1;

            recBackground.Width = recBackground.Width + w2 - 2;
            recBackground.Height = (recBackground.Height / 2 - 2) + recBackground.Height / 4;
            recImage.Width = (recImage.Width + w2) / 2 - 2;
            recImage.Height = (recImage.Height / 2 - 2) + recImage.Height / 4;
            recString.Width = (recString.Width + w2) / 2 - 2;
            recString.Height = (recString.Height / 2 - 2) + recString.Height / 4;

            e.Graphics.FillRectangle(new SolidBrush(this.dataGridView1.ColumnHeadersDefaultCellStyle.BackColor), recBackground);
            StringFormat format = new StringFormat();
            format.Alignment = StringAlignment.Center;
            format.LineAlignment = StringAlignment.Center;
            e.Graphics.DrawString(monthes[j / 2],
                this.dataGridView1.ColumnHeadersDefaultCellStyle.Font,
                new SolidBrush(this.dataGridView1.ColumnHeadersDefaultCellStyle.ForeColor),
                recString,
                format);
            e.Graphics.DrawImage(imglists[j], recImage);
            h++;
            j += 2;
        }
        ///
        /// Initializing variable yang akan digunakan untuk menggambar
        /// Flag untuk menandakan posisi koordinat untuk looping gambar
        ///
        string stat = "";
        string awal = dataGridView1.Rows[0].HeaderCell.Value.ToString().Substring(6).ToString();
        string akhir = dataGridView1.Rows[6].HeaderCell.Value.ToString().Substring(6).ToString();
        tglAwal = Convert.ToDateTime(awal);
        tglAkhir = Convert.ToDateTime(akhir);
        awal = tglAwal.ToString("yyyy-MM-dd");
        akhir = tglAkhir.ToString("yyyy-MM-dd");
        var split = new String[25];
        int countRows = 0;
        int countColumns = 0;
        int countRows2 = myActivity.getActivityPagi2(awal, akhir).Tables[0].Rows.Count;
        int countColumns2 = myActivity.getActivityPagi2(awal, akhir).Tables[0].Columns.Count;
        int countRows3 = 0;
        Font font1 = new Font("Arial", 10, FontStyle.Bold, GraphicsUnit.Point);
        Font font2 = new Font("Arial", 8, FontStyle.Regular, GraphicsUnit.Point);
        int[,] flag = new int[dataGridView1.Rows.Count, dataGridView1.Columns.Count];
        int[,] flag2 = new int[dataGridView1.Rows.Count, dataGridView1.Columns.Count];
        int[,] flag3 = new int[dataGridView1.Rows.Count, dataGridView1.Columns.Count];
        int dgRows = dataGridView1.Rows.Count;
        int dgColumns = dataGridView1.Columns.Count;

        ///
        /// Draw Background Colour dan Draw String
        /// Pertama Looping semua isi data set kedalam string array
        /// Kemudian Looping per Cell untuk menggambar Stringnya dan Fill Rectangle
        /// 

        string[,] activity = new string[myActivity.getActivityPagi(awal, akhir).Tables[0].Rows.Count, 6];

        string[,] activity2 = new string[myActivity.getActivityPagi2(awal, akhir).Tables[0].Rows.Count, 6];
        for (int i = 0; i < countRows2; i++)
        {
            for (int j = 0; j < countColumns2; j++)
            {
                activity2[i, j] = myActivity.getActivityPagi2(awal, akhir).Tables[0].Rows[i][j].ToString();
            }
        }


        for (int i = 0; i < dgRows; i++)
        {
            headerValue = dataGridView1.Rows[i].HeaderCell.Value.ToString();
            for (int j = 0; j < dgColumns; j++)
            {
                // Set sessi

                split = headerValue.Split(',');
                time = DateTime.Parse(split[1]);

                substring1 = dataGridView1.Columns[j].Name.Substring(dataGridView1.Columns[j].Name.Length - 4, 4);
                substring2 = dataGridView1.Columns[j].Name.Substring(dataGridView1.Columns[j].Name.Length - 5, 5);
                if (substring1 == "Pagi")
                {
                    ses = "Pagi";
                }
                else
                    if (substring2 == "Siang")
                    {
                        ses = "Siang";
                    }
                // set count row and column for loop
                countRows = myActivity.getActivityBySessi(awal, akhir, ses, time.ToString("yyyy-MM-dd")).Tables[0].Rows.Count;
                countColumns = myActivity.getActivityBySessi(awal, akhir, ses, time.ToString("yyyy-MM-dd")).Tables[0].Columns.Count;
                // set data from dataset to variable array 2 d

                ///
                /// Looping di bawah membuat lag karena melakukan query pada class activity(myActivity) setiap melakukan loop
                /// dan berada di 4 Nested loop
                /// -----------------------------------------------------------------------------------------------------------------------
                ///


                for (int s = 0; s < countRows; s++)
                {
                    for (int d = 0; d < countColumns; d++)
                    {
                        activity[s, d] = myActivity.getActivityBySessi(awal, akhir, ses, time.ToString("yyyy-MM-dd")).Tables[0].Rows[s][d].ToString();
                    }
                    r1 = this.dataGridView1.GetCellDisplayRectangle(j, i, true);
                    r2 = this.dataGridView1.GetCellDisplayRectangle(j, i, true);
                    r3 = this.dataGridView1.GetCellDisplayRectangle(j, i, true);
                    w2 = this.dataGridView1.GetCellDisplayRectangle(j, i, true).Width;
                    r1.X += 1;
                    r1.Y += flag[i, j] + 1;
                    r1.Width = 65;
                    r1.Height = 15;
                    r2.X += 1;
                    r2.Y += flag2[i, j] + 15;
                    r2.Width = 65;
                    r2.Height = 15;
                    r3.X += 1;
                    r3.Y += flag3[i, j] + 30;
                    r3.Width = 70;
                    r3.Height = 46;
                    if (r1.Y == 1 && r1.X == 1)
                        break;
                    flag[i, j] = flag[i, j] + 76;
                    flag2[i, j] = flag2[i, j] + 76;
                    flag3[i, j] = flag3[i, j] + 76;

                    if (flag3[i, j] == dataGridView1.Rows[i].MinimumHeight)
                    {
                        dataGridView1.Rows[i].MinimumHeight += 76;
                    }
                    StringFormat format = new StringFormat();
                    StringFormat format2 = new StringFormat();
                    format2.Alignment = StringAlignment.Near;
                    format2.LineAlignment = StringAlignment.Near;
                    format.Alignment = StringAlignment.Center;
                    format.LineAlignment = StringAlignment.Center;

                    if (time == Convert.ToDateTime(activity[s, 5]) && dataGridView1.Columns[j].Name == activity[s, 3] + activity[s, 4])
                    {

                        if (coloring.getColor(activity[s, 1]) == Color.Black)
                        {
                            e.Graphics.FillRectangle(new SolidBrush(Color.White), r1);
                            e.Graphics.DrawString(activity[s, 0],
                                font1,
                                new SolidBrush(this.dataGridView1.ColumnHeadersDefaultCellStyle.ForeColor),
                                r1,
                                format2);
                            e.Graphics.FillRectangle(new SolidBrush(coloring.getColor(activity[s, 1])), r2);
                            e.Graphics.DrawString(activity[s, 1],
                                font1,
                                new SolidBrush(Color.White),
                                r2,
                                format);
                            e.Graphics.DrawString(activity[s, 2],
                                font2,
                                new SolidBrush(this.dataGridView1.ColumnHeadersDefaultCellStyle.ForeColor),
                                r3,
                                format2);
                        }
                        else
                            if (myProblem.getIdProblem(myActivity.getIdDetActivity(activity[s, 3], activity[s, 4], Convert.ToDateTime(activity[s, 5]).ToString("yyyy-MM-dd"), activity[s, 0], activity[s, 1]).Tables[0].Rows[0][0].ToString(), activity[s, 0], activity[s, 1]).Tables[0].Rows.Count >= 1)
                            {
                                e.Graphics.FillRectangle(new SolidBrush(Color.White), r1);
                                e.Graphics.DrawString(activity[s, 0],
                                    font1,
                                    new SolidBrush(Color.Red),
                                    r1,
                                    format2);
                                e.Graphics.FillRectangle(new SolidBrush(coloring.getColor(activity[s, 1])), r2);
                                e.Graphics.DrawString(activity[s, 1],
                                    font1,
                                    new SolidBrush(this.dataGridView1.ColumnHeadersDefaultCellStyle.ForeColor),
                                    r2,
                                    format);
                                e.Graphics.DrawString(activity[s, 2],
                                    font2,
                                    new SolidBrush(this.dataGridView1.ColumnHeadersDefaultCellStyle.ForeColor),
                                    r3,
                                    format2);
                            }
                            else
                            {
                                //label1.Text = myActivity.getIdActivity(activity[k, 3], activity[k, 4], Convert.ToDateTime(activity[k, 5]), activity[k, 0]).Tables[0].Rows[0][1].ToString();
                                e.Graphics.FillRectangle(new SolidBrush(Color.White), r1);
                                e.Graphics.DrawString(activity[s, 0],
                                    font1,
                                    new SolidBrush(this.dataGridView1.ColumnHeadersDefaultCellStyle.ForeColor),
                                    r1,
                                    format2);
                                e.Graphics.FillRectangle(new SolidBrush(coloring.getColor(activity[s, 1])), r2);
                                e.Graphics.DrawString(activity[s, 1],
                                    font1,
                                    new SolidBrush(this.dataGridView1.ColumnHeadersDefaultCellStyle.ForeColor),
                                    r2,
                                    format);
                                e.Graphics.DrawString(activity[s, 2],
                                    font2,
                                    new SolidBrush(this.dataGridView1.ColumnHeadersDefaultCellStyle.ForeColor),
                                    r3,
                                    format2);

                            }//end else
                    }//end if time
                }

                ///
                ///-----------------------------------------------------------------------------------------------------------------------
                ///

                //base.Invalidate();
                //base.InvokePaint(dataGridView1, e);
                //base.Refresh();
                //base.Validate();
                // Create paint fill rectangle and draw string
                //for (int k = 0; k < countRows; k++)
                //{

                //}// end for loop

                //headerValue = dataGridView1.Rows[i].HeaderCell.Value.ToString();

                //split = headerValue.Split(',');
                //time = DateTime.Parse(split[1]);
                countRows3 = myActivity.getCountMstActivity(time.ToString("yyyy-MM-dd"), ses);
                for (int z = 0; z < countRows3; z++)
                {

                    if (myActivity.getIdActivity(time.ToString("yyyy-MM-dd"), ses).Tables[0].Rows.Count > 0)
                    {
                        stat = myActivity.getIdActivity(time.ToString("yyyy-MM-dd"), ses).Tables[0].Rows[z][1].ToString();
                    }

                    if (stat == "IZIN" || stat == "SAKIT" || stat == "CUTI")
                    {

                        for (int l = 0; l < countRows2; l++)
                        {
                            if (time == Convert.ToDateTime(activity2[l, 2]) && dataGridView1.Columns[j].Name == activity2[l, 0] + activity2[l, 1])
                            {

                                r1 = this.dataGridView1.GetCellDisplayRectangle(j, i, true);
                                r2 = this.dataGridView1.GetCellDisplayRectangle(j, i, true);
                                r3 = this.dataGridView1.GetCellDisplayRectangle(j, i, true);

                                int w2 = this.dataGridView1.GetCellDisplayRectangle(j, i, true).Width;
                                r1.X += 1;
                                r1.Y += flag[i, j] + 1;
                                r1.Width = 65;
                                r1.Height = 15;
                                r2.X += 1;
                                r2.Y += flag2[i, j] + 15;
                                r2.Width = 65;
                                r2.Height = 15;
                                r3.X += 1;
                                r3.Y += flag3[i, j] + 30;
                                r3.Width = 70;
                                r3.Height = 46;
                                if (r1.Y == 1 && r1.X == 1)
                                    break;
                                flag[i, j] = flag[i, j] + 76;
                                flag2[i, j] = flag2[i, j] + 76;
                                flag3[i, j] = flag3[i, j] + 76;

                                if (flag3[i, j] == dataGridView1.Rows[i].MinimumHeight)
                                {
                                    dataGridView1.Rows[i].MinimumHeight += 76;
                                }
                                StringFormat format = new StringFormat();
                                StringFormat format2 = new StringFormat();
                                format2.Alignment = StringAlignment.Near;
                                format2.LineAlignment = StringAlignment.Near;
                                format.Alignment = StringAlignment.Center;
                                format.LineAlignment = StringAlignment.Center;

                                e.Graphics.DrawString(stat,
                                    font1,
                                    new SolidBrush(this.dataGridView1.ColumnHeadersDefaultCellStyle.ForeColor),
                                    r1,
                                    format2);

                            }

                        }
                    }//End if izin sakit cuti
                    if (stat == "HADIR")
                    {

                    }//end if HADIR

                }// end for loop Z=0
                //this.dataGridView1.InvalidateColumn(j);
            }//end loop column

        }// end for loop row

        //DrawingControl.ResumeDrawing(dataGridView1);
    }
Was it helpful?

Solution

You could create a memory bitmap that you only create and draw once. If it already exists, simply draw the bitmap instead of performing all the drawing.

Pseudo code like this:

Bitmap offscreen = null;

private void dataGridView1_Paint(object sender, PaintEventArgs e)
{
    if (offscreen == null)
    {
        offscreen = new Bitmap(...);
        using (Graphics g = Graphics.FromImage(offscreen))
        {
            // Do all the drawing onto the bitmap. Please make
            // sure to offset all coordinates accordingly, so that
            // they are relative to (0,0)!!
        }
    }

    e.Graphics.DrawImage(offscreen);
}

If you want to draw every cell, it may also be a solution to handle the CellPainting event and draw every cell individually.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top