Merhaba, Ziyaretçi. Lütfen giriş yapın veya üye olun.

Kullanıcı adınızı, parolanızı ve aktif kalma süresini giriniz

  Gelişmiş Arama
insanın içinde varsa, commodore.gen.tr açığa çıkarır bunu.. bir nevi retro olaylarının dolunayıyız.(Arda)
commodore.gen.trGenel KategoriProjeCSharp ile Datagridview renklendirmede çok bekletiyor.
Sayfa: [1]   Aşağı git
Yazdır
Gönderen Konu: CSharp ile Datagridview renklendirmede çok bekletiyor.  (Okunma Sayısı 5304 defa)
0 Üye ve 1 Ziyaretçi konuyu incelemekte.
programci42
Üye
***
Mesaj Sayısı: 196


Üyelik Bilgileri
« : Mart 20, 2020, 08:57:23 ÖÖ »

Arkadaşlar şöyle bir sorunum var C# ile datagridview deki satırları renklendirmek istiyorum ve şöyle bir metod yazdım gayet de güzel çalışıyor ancak şu an mesela 1224 kayıt var tabloda şimdi ben bu kayıtları SQL Server dan çektiğimde şak diye anında karşıma çıkıyor yani verileri çok hızlı geliyor güzel ancak mesela tabloda bazı veriler var işte örnek olarak PASS / FAIL gibi değerler şimdi ben PASS yazanları yeşile FAIL yazanları da kırmızıya boyuyorum ki hata olanlar yani FAIL olanlar olay fark edilebilsin, fakat 100 - 150 kayıt varken çok bekletmiyor bu metod ancak dediğim gibi 1224 kayıt var şu an ve nerdeyse en az 1 dk bekletiyor çok uzun bir süre bu buna nasıl bir çözüm bulabiliriz acaba kodları aşağıya yapıştırdım.

Kod:
void Renkver()
        {
            if (datagrid.DataSource != null)
            {
                ((Form1)Application.OpenForms["Form1"]).bar.Value = 0;
                ((Form1)Application.OpenForms["Form1"]).bar.Maximum = datagrid.Rows.Count;
                for (int x = 0; x < datagrid.Rows.Count; x++)
                {
                    if (Convert.ToString(datagrid.Rows[x].Cells["Durum"].Value) == "PASS")
                    {
                        datagrid.Rows[x].Cells["Durum"].Style.BackColor = Color.Green;
                        datagrid.Rows[x].Cells["Durum"].Style.ForeColor = Color.White;
                    }
                    else if (Convert.ToString(datagrid.Rows[x].Cells["Durum"].Value) == "FAIL")
                    {
                        datagrid.Rows[x].Cells["Durum"].Style.BackColor = Color.Maroon;
                        datagrid.Rows[x].Cells["Durum"].Style.ForeColor = Color.White;
                    }

                    if (Convert.ToString(datagrid.Rows[x].Cells["bitti"].Value) == "true" || Convert.ToString(datagrid.Rows[x].Cells["bitti"].Value) == "EVET")
                    {
                        datagrid.Rows[x].Cells["bitti"].Value = "EVET";
                        datagrid.Rows[x].Cells["bitti"].Style.BackColor = Color.Green;
                        datagrid.Rows[x].Cells["bitti"].Style.ForeColor = Color.White;
                    }
                    else if (Convert.ToString(datagrid.Rows[x].Cells["bitti"].Value) == "false" || Convert.ToString(datagrid.Rows[x].Cells["bitti"].Value) == "HAYIR")
                    {
                        datagrid.Rows[x].Cells["bitti"].Value = "HAYIR";
                        datagrid.Rows[x].Cells["bitti"].Style.BackColor = Color.Yellow;
                        datagrid.Rows[x].Cells["bitti"].Style.ForeColor = Color.White;
                    }
                    ((Form1)Application.OpenForms["Form1"]).bar.Value++;
                    ((Form1)Application.OpenForms["Form1"]).Refresh();
                }
            }
        }
Logged
Theoden (CYON4D)
Deneyimli
*****
Mesaj Sayısı: 1.758



Üyelik Bilgileri WWW
« Yanıtla #1 : Mart 20, 2020, 10:16:24 ÖÖ »

Selamlar, ben de benzer bir tablo renklendirme işlemi yapmıştım.
Binlerce kayıt olmasına rağmen en fazla 3 saniye gibi bir gecikme gördüm şimdilik.

Kod:
           for (int i = 0; i < mali_dataGridView.Rows.Count; i++)
            {
                string type = mali_dataGridView[4, i].Value.ToString();

                if (type == "Fatura Kes" || type == "Ödeme Yap")
                {
                    mali_dataGridView[4, i].Style.ForeColor = Color.DarkRed;
                    mali_dataGridView[5, i].Style.ForeColor = Color.DarkRed;
                    mali_dataGridView[6, i].Style.ForeColor = Color.DarkRed;
                }

                if (type == "Maaş Ode")
                {
                    mali_dataGridView[4, i].Style.ForeColor = Color.DarkRed;
                    mali_dataGridView[5, i].Style.ForeColor = Color.DarkRed;
                }

            }

Sizin kod ile arasındaki iki fark "Cells["bitti"].Value = "EVET"/"HAYIR";" kısmındaki Cell Value değişimi ve Background renginin de değişiyor olması.

Bu iki işlemi kapatarak bir test etmenizi tavsiye ederim.
Yani Cell'lerin değerlerini değiştirmeden sadece renklerini değiştirmek işlemi hızlandırabilir.
Value'ları dinamik değiştirmek her değişen value için datagridview'de "column size changed" event'i tetikleyebilir.
Bu da her satır için bu event'in tekrar tekrar çağırılması ve vakit kaybına sebep olacaktır.

Ayrıca cell'lerin değerini değiştirmek o cell'in datatype'ını değiştirmek anlamına da geliyor yanlış hatırlamıyorsam.
Yani sizin durumunuzda değişiklik yapılan cell'in tipi bool'dan string'e dinamik olarak değiştirilmek zorunda kalınıyor. Bu da bir etken olabilir.

Kodu sadeleştirip tek tek ekstra özellikler ekledikçe test ederseniz hangi aşamanın en çok vakit aldığını izole edip bulabilirsiniz.

EDIT:

En alttaki Refresh() methodu gözümden kaçmış, diğer arkadaşların belirttiği gibi kesinlikle yavaşlıgın sebeplerinden biri bu.
« Son Düzenleme: Mart 21, 2020, 18:12:07 ÖS Gönderen: Theoden (Arethrid) » Logged

Voltron
Uzman
*****
Mesaj Sayısı: 2.159



Üyelik Bilgileri
« Yanıtla #2 : Mart 20, 2020, 12:13:36 ÖS »

Renklendirme işlemini CellFormatting event'i ile yapmayı deneyebilirsin.

https://stackoverflow.com/questions/1630066/c-sharp-winforms-datagridview-background-color-rendering-too-slow
Logged

Metal grupları çok bağırıyor. haklıyken haksız duruma düşüyorlar...
ibo1973
Uzman
*****
Mesaj Sayısı: 2.440


Üyelik Bilgileri
« Yanıtla #3 : Mart 20, 2020, 14:44:22 ÖS »

bence en hızlı olabilecek kod sadece o anda ekranda görünen kısımları renklendirerek elde edersin diye düşünüyorum  yani 100000 değeri renklendirmek yerine sadece ekranda görünen kısmı renklerdir.
Logged
egemur
Üye
****
Mesaj Sayısı: 388



Üyelik Bilgileri
« Yanıtla #4 : Mart 20, 2020, 18:10:25 ÖS »

Merhaba, Form1 for döngüsü içinde refresh ediliyor her seferinde. Bu gerekli mi? Değilse döngüden çıkılanca bir kerede refresh yapılabilir.  

Bir de if, else if yapısında eğer sadece pass ve fail değerleri varda else if yerine else de kullanılabilir.
« Son Düzenleme: Mart 20, 2020, 18:12:03 ÖS Gönderen: egemur » Logged

Commodore 64/64c - 1541 Ultimate+ - Ultimate 64 Elite
Amiga 500 - Gotek Floppy Drive
ercanersoy
Deneyimli
*****
Mesaj Sayısı: 968


Üyelik Bilgileri WWW
« Yanıtla #5 : Mart 21, 2020, 08:28:07 ÖÖ »

Evet, yenileme fonksiyonu sürekli çalıştırılıyor ve penceredeki bileşenler sürekli yenilendiği için program bayağı yavaşlar.
Logged
Theoden (CYON4D)
Deneyimli
*****
Mesaj Sayısı: 1.758



Üyelik Bilgileri WWW
« Yanıtla #6 : Mart 21, 2020, 11:58:56 ÖÖ »

En alttaki Refresh() methodu gözümden kaçmış, diğer arkadaşların belirttiği gibi yavaşlıgın sebeplerinden biri bu.
« Son Düzenleme: Mart 21, 2020, 18:11:52 ÖS Gönderen: Theoden (Arethrid) » Logged

programci42
Üye
***
Mesaj Sayısı: 196


Üyelik Bilgileri
« Yanıtla #7 : Mart 21, 2020, 14:52:56 ÖS »

Evet arkadaşlar yorumlarınız için çok teşekkür ederim yavaşlığın sebebini buldum
datagrid.Rows
  • .Cells["bitti"].Value = "EVET";
datagrid.Rows
  • .Cells["bitti"].Value = "HAYIR";

bu iki kod yüzünden çok yavaşlıyormuş şimdi en fazla 2 sn bekletiyor

bu arada o progressbar ve refresh olayını ne kadar uzun süreceğini takip etmek için koymuştum dediğiniz gibi bunlarda iyice yavaşlatıyor zaten.

Peki ama ben o true - false olayını hesaplamaları ve işlemleri daha kolay yapabileyim diye veritabanına öyle kaydettirdim ama ekranda listelerken insanlara Türkçe görünsün istiyorum bunu yavaşlama olmadan nasıl halledebilirim?
Logged
Theoden (CYON4D)
Deneyimli
*****
Mesaj Sayısı: 1.758



Üyelik Bilgileri WWW
« Yanıtla #8 : Mart 21, 2020, 18:21:02 ÖS »

Yukarda yazığım gibi .Cells["bitti"].Value = "EVET"; gibi bir işlem column size ve type değişim fonksiyonlarını tetikler ve boşa vakit kaybettirir.

Diğer soruyla ilgili de iki farklı çözüm olabilir.

1. Eğer SQL kullanılıyorsa SQL komutuyla true/false evet/hayır olarak aynı SQL sorgusunun içinde dinamik bir şekilde değiştirilebilir.
Kod:
CASE WHEN column = 'TRUE' then 'EVET' else 'HAYIR' end
Buradaki "column" yazan yer SQL'deki column ismi neyse o olacak.
En hızlı ve kolay çözüm budur, eğer veriler SQL'den geliyorsa bu yöntemi tavsiye ederim.


2. Ya da buffer olarak bir DataTable objesi yaratılır, önce bu DataTable tek seferde doldurulur. Sonra gerekli evet/hayır değişiklikleri bu DataTable üzerinde yapıldıktan sonra komple formun içinde görünen DataGridView'e gönderilir. Böylece gridview'in cell data type'larının tekrardan değiştirilmesi gerekmez. Ama bu yöntem yine de çok hızlı olmayacaktır.


Ayrıca "((Form1)Application.OpenForms["Form1"]).bar.Value++;" satırının başındaki "((Form1)Application.OpenForms["Form1"])" kısmına gerek yoktur.
"this.bar.Value++; ya" da bar ismi doğruysa "bar.Value++;" yazılabilir.
"bar.Value++;" progressbar'ın value changed event'ini tetikleceği için ayreten aşağıda "((Form1)Application.OpenForms["Form1"]).Refresh();" satırındaki bütün formu refresh eden bir fonksiyona gerek olmaması lazım. Bu kaldırılabilir. Eğer bar ilerlemiyorsa en azından "bar.Refresh();" olarak değiştirilebilir.
Bütün formu sürekli Refresh() yapmanın hiçbir anlamı yok aslında.
« Son Düzenleme: Mart 21, 2020, 18:31:27 ÖS Gönderen: Theoden (Arethrid) » Logged

NoStres
Deneyimli
*****
Mesaj Sayısı: 633


One Love, One Heart, One Destiny


Üyelik Bilgileri WWW
« Yanıtla #9 : Mart 21, 2020, 23:38:41 ÖS »

Çok fark etmese de; veri kaç olursa olsun, işlem bandını görüntülemek için, ProgressBar'ı 10'a bölünerek kullanılabilecek bir kod yazdım, böylece for içerisinde kullanılırken her adım için gereksiz işlem yapmayacak, belki işine yarar.

Zip ekte.

* ProgressBar_Kisaltma.zip (39.19 KB - Yükleme: 164 kez.)
Logged

EMREZ
Deneyimli
*****
Mesaj Sayısı: 1.904



Üyelik Bilgileri
« Yanıtla #10 : Mart 22, 2020, 20:20:57 ÖS »

Bekletmesi notmal değil. tabi kaç satır olduğuna ve kodun çalıştığı cihazın durumu değiştirir. ben genelde aylık yıllık vardiya listesinde kullanıyorum, yada editlemei excel benzeri vs.
aynı sayfada 7 grid ve 35 pesonel var. çalışma saati isim gibi değerleri var her row da

 protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
                     //   WHEN (durum  = 0 ) THEN 'Devre Çıkarmış'
//WHEN (durum  = 1) THEN 'Orjinal'
//WHEN (durum  = 2 ) THEN 'Devralmış'
//WHEN (durum  = 3 ) THEN 'Raporlu'
        int col = 0;
        DateTime dt;
        DateTime.TryParse(Session["tarih"].ToString(), out dt);

        if (dt.ToString("dd-MM-yyyy") == DateTime.Now.ToString("dd-MM-yyyy")) { col = 1; }
        int g=0;
            for (int i = 0; i <= GridView1.Rows.Count - 1; i++)
            {

                string myClassVal = GridView1.Rows.Cells[0].Text;
               

                switch (myClassVal.ToString())
                {
                    case "0":
                        GridView1.Rows.Cells[1].BackColor = System.Drawing.Color.LightCoral;
                        break;
                    case "1":
                        if (col == 1)
                        {
                            GridView1.Rows.Cells[1].BackColor = System.Drawing.Color.LightGray;
                        }
                        break;

                    case "2":
                        GridView1.Rows.Cells[1].BackColor = System.Drawing.Color.PaleTurquoise;
                        break;
                    case "3":
                        GridView1.Rows.Cells[1].BackColor = System.Drawing.Color.YellowGreen;
                        break;

                    default:
                       
                        break;
                }


            }
Logged

this is amiga speaking.
Sayfa: [1]   Yukarı git
Yazdır
Gitmek istediğiniz yer: