Bu site emekli olmuştur. Arşiv amaçlı olarak BT AKADEMİ sponsorluğunda yayın hayatına devam etmektedir.




C#nedir?com
 
YAZAR HAKKINDA
Recep  Daban
Recep Daban
http://www.csharpnedir.com/
İletişme geçmek için tıklayın.
1 Makalesi yayınlanmakta.
Yazar hakkında detaylı bilgi için tıklayın.
Yayınlanan diğer makaleleri için tıklayın.
İlgili etiketler: (e.columnindex 1000000 arasinda datagridview dataobject degerler e.value initgrid() kaydirma m_data private public return veriler virtualmode C# / VC#/.NET Recep Daban
 
YAZI HAKKINDA
Türü : Makale
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
Seviyesi : Orta
Kategori : C# / VC#/.NET
Yayınlanma Tarihi : 23.8.2007
Okunma Sayısı : 54368
Yorum Sayısı : 5     yorum yaz
Site İçi AramaSİTE İÇİ ARAMA
Üye Girişini AçÜye GİRİŞİ
Üye girişi için tıklayın.
Kullanıcı Adı
Şifre
 
Beni her zaman hatırla
Bir hafta boyunca kullanıcı bilgilerinizi kullanıcı çıkışı yapana kadar hatırlar. (Paylaşılan bilgisayarlarda önerilmez.)
 
Şifremi / Kullanıcı Adımı unuttum.
 
.net TV RSS Serbest KÖŞE (?)
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
emre TAŞ
Silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
Makale Gönder Bende Yazmak İstiyorum
.net TV RSSBlogroll
Turhal Temizer
Conda install environment.yml Package 21.11.2024
Turhal Temizer
Mac OS/X Removing CUDA 21.11.2024
Burak Selim Şenyurt
Rust ile ECS Yaklaşımını Anlamak 21.11.2024
Burak Selim Şenyurt
Birlikte Rust Öğrenelim Serisi 21.11.2024
  Diğer Herşey
Sponsorlar
BT Akademi
Medya Portakal
Video Hosting Sponsoru
Csharpnedir.com bir Ineta üyesidir
Uzman Abi
Her Yönüyle C# - Sefer Algan
DataGridView Ile VirtualMode'da Çalışmak
 
Kapat
Sayfayı Yazdır Sık Kullanılanlara Ekle Arkadaşıma Gönder MySpace Del.Ico.Us Digg Facebook Google Mixx Reddit StumbleUpon
Bu makalemde size DataGridView de VirtualMode da çalışmanın nasıl olduğundan bahsedeceğim.

Öncelikle buna neden ihtiyaç duyuyoruz veya nerde ihtiyaç duyacağız, bunu biraz açmak istiyorum. Veritabanı uygulamalarımızda çok sayıda veriyle uğraşmaktayız ve bunları bizim için en iyi şekilde gösterebilen tabii ki DataGridView kontrolüdür.

DataGridView .Net Framework 2.0 gelen bir kontrol ve eskiden kullandığımız DataGrid in geliştirilmiş ve birçok özelliğin eklenmiş hali. Daha doğrusu bu kontrolle çalışmak çok daha esnek. Neyse konuyu dağıtmayalım. DataGridView de verilerimizi gösterirken muhakkak gridin sağ tarafında veya altında ya da her iki yerde birden ScrollBar larla karşılaşırız. Bu ScrollBar lar sayesinde verilerimiz arasında gezinti yapabiliyoruz.

Bazen bu gezinme olayı hiç de kolay olmaz. Diyelimki elimizde 1000000 (bir milyon) satır gibi kayıt içeren veritabanında bir tablomuz var. Bu kadar veriyi DataGridView de gösterebiliriz fakat sistemimize göre bayağı bir performans kaybı yaşayacağız çünkü bu kadar veriyi bir seferde göstermek sistemimizdeki kaynakları çok tüketecektir. Ve görüceğiz ki veriler arasında dolaşmak hiç de kolay olmayacaktır.

Gelin bunu bir örnek üstünde görelim ve neden VirtualMode da çalışmak daha avantajlı beraber göz atalım.

Öncelikle yeni bir C# projesi oluşturup, bir DataGridView ve bir Button ekliyoruz.




DataGridView nesnemizin Dock özelliğini Top olarak ayarladık. Nesnemizin ismini m_Data, Buttonumuzun ismini btnHucreSayisi olarak değiştirdik.

VirtualMode da çalışmak için DataGridView nesnemizin VirtualMode özelliğini true yapmalıyız. Bunu dizayn ekranındaki özellikler bölümünden yapabileceğimiz gibi kod tarafında da atayabiliriz.

Daha sonra kod ekranını açarak bir class oluşturuyoruz. Bu class DataGridView e ekliyeceğimiz veriler için bir şablon olucak ve bunun bir koleksiyonu yaparak 1000000 kayıtı sağlıyacak bir yapı oluşturacağız.

class DataObject //DataObject nesnemiz....
{

    private int m_Id;
    private int m_Val;

    public int Id
    {
        get { return m_Id; }
        set { m_Id = value; }
    }
    public int Val
    {
        get { return m_Val; }
        set { m_Val = value; }
    }
}
Veri kümemizi oluştururken Generics lerden yararlanacağız. İki veri kümesi oluşturarak biri bizim verilerimizi, diğeri gezilen satırları tutacak.

private List<DataObject> m_Data = new List<DataObject>();
private List<bool> m_Visited = new List<bool>();


Şimdi değinmemiz gereken önemli bir nokta var. DataGridView de VirtualMode da çalışırken hücrelerin hepsi bir anda gride yüklenmez. Bunun yerine o anda ekranda gösterilenler grid de gösterilir. Yani kaydırma çubuklarıyla aşağı-yukarı veya sağa-sola yaptığımızda sadece durduğumuz anda ki hücreler gösterilecektir. Bu da bellekte çok miktarda verinin yer kaplamamasını sağlayarak performans sağlayacaktır. Aynı zamanda bu kadar kayıt arasında gezmek çok rahat olucaktır.

Bu gösterim esnasında DataGridView de sadece VirtualMode da çalışırken meydana gelen bir olay tetiklenecektir. CellValueNeeded, bu olayı kullanarak verilerimizi DataGridView içersine yerleştireceğiz.

Şimdi kodlarımızın tamamına bakarak ne yapmaya çalıştığımıza ve bize ne fayda sağlayacağına bakalım.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace DataGridView_Virtual_Mode
{
    public partial class Form1 : Form
    {
        private List<DataObject> m_Data = new List<DataObject>(); //Genericler List ye DataObject nesnesi gönderilerek List artık DataObject tipinden nesneler alıyor..
        private List<bool> m_Visited = new List<bool>(); // Genericler List ye "bool" gönderilerek List artık "bool" tipinden nesneler alıyor..
        public Form1()
        {
             InitializeComponent();
             m_Grid.CellValueNeeded += new DataGridViewCellValueEventHandler(m_Grid_CellValueNeeded); //Virtula Modda tetiklenecek CellValueNeeded olayı oluşturuluyor..
             InitData(); //Veriler nesnelerimize yükleyen metot ....
             InitGrid(); //Grid için gerekli işlemler.....
        }
        void m_Grid_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
        {
            // Bu olay hangi hücre görütülenecekse onun için tetiklenir....e burda gerekli değerleri tutuyor...
            m_Visited[e.RowIndex] = true;
             if (e.ColumnIndex == 0)
             {
                 e.Value = m_Data[e.RowIndex].Id;
             }
             else if (e.ColumnIndex == 1)
            {
                 e.Value = m_Data[e.RowIndex].Val;
             }
             else if (e.ColumnIndex == 2)
             {
                 Random rnd = new Random();
                 e.Value = rnd.Next(1, 10000000);
             }
        }
        private void InitData()
        {
             for (int i = 0; i < 10000001; i++) //Döngüyle 1000000 tane DataObject nesnesi oluşturuluyor ve m_Data Listesine ekleniyor...
             {
                m_Visited.Add(false); // m_Visited nesnesine 1000000 tane false ekleniyor..Bu liste kaç satırı gezdiğimizi tutmak için...
                DataObject obj = new DataObject();
                obj.Id = i; //Değerler atanıyor...rasgele burda döngüdeki i değeri kullanıldı....
                obj.Val = i * 2;
                m_Data.Add(obj);
             }
        }

         private void InitGrid() //Grid işlemleri.....
         {
             m_Grid.ReadOnly = true;
             m_Grid.AllowUserToAddRows = false;
             m_Grid.AllowUserToDeleteRows = false;
             m_Grid.ColumnCount = 3; //Kaç kolon olacağı belirleniyor...
             m_Grid.Columns[0].Name = "Val 1"; //Kolonların isimleri veriliyor...
             m_Grid.Columns[1].Name = "Val 2";
             m_Grid.Columns[2].Name = "Val 3";
             m_Grid.Rows.Add(); //Boş bir satır DataGridView(ismi m_Grid) e ekleniyor...
             m_Grid.Rows.AddCopies(0, 1000000); //=. satırın 1000000 kopyası oluşturuluyor....
             //m_Grid.DataSource = m_Data; // Virtual mode aktif değilken dataların işlemesi
         }
         private void btnHucreSayisi_Click(object sender, EventArgs e)
         {
             int count = 0;

             for (int i = 0; i < m_Visited.Count - 1; i++)
             {
                 if (m_Visited[i])
                     count++;
             }
             MessageBox.Show(count.ToString());
         }
}

     class DataObject //DataObject nesnemiz....
     {

         private int m_Id;
         private int m_Val;
   
         public int Id
         {
             get { return m_Id; }
             set { m_Id = value; }
         }
         public int Val
         {
              get { return m_Val; }
              set { m_Val = value; }
         }
    }
}
Kodlardan da görüceğiniz gibi InitData() ve InitGrid() adında iki methot oluşturduk. Gridimize üç kolon ekleyerek bu kolonların isimlerini verdik. Esasında class ımızda veri olarak iki (m_Id,m_Val)alan gözükürken Gridimize üç kolon ekledik. Buradaki üçüncü kolondaki verileri başka türlü oluşturacağız ve burda karşımaza bir durum çıkacak. Bundan ilerleyen kısımda bahsedeceğim. InitGrid() kısmında gridimize m_Grid.Rows.Add(); satırıyla boş bir satır ekledik. Daha sonra bu satırın m_Grid.Rows.AddCopies(0, 1000000); satırıyla 1000000 kopyasını oluşturduk.

InitData() kısmıyla da verileri oluşturuyoruz. Bu kısımda 1000000 kadar bir döngü açıp iki koleksiyonumuzu dolduruyoruz.

m_Visited.Add(false); satırıyla daha herhangibir kayıt görüntelemediğimizden ziyaret edilen satırların hepsine false değeri atanıyor.

Daha sonra DataObject nesneleri oluşturup bunların içideki değerler atanarak m_Data listemize şu satırlarla ekliyoruz.

DataObject obj = new DataObject();
obj.Id = i;
obj.Val = i * 2;
m_Data.Add(obj);


Şimdi uygulamamız çalıştırmaya hazır hale geldi. Önceden de bahsettiğim gibi VirtualMode da çalışırken CellValueNeeded olayı meydana gelir. Biz de bu olayda o anda görüntületmeye çalıştığımız hücrelerin değerlerini atayacağız.

Bu olayda herhangi bir hücre görüntületmeye çalıştığımızda öncelikle o satırın görüntülendiğini bildiren satırı yazıyoruz.

m_Visited[e.RowIndex] = true;

Daha sonra bu olayda e parametresinden yararlanarak hangi kolonda ve satırda olduğumuzu yani hangi hücre de olduğumuzu bularak bu hücreye daha önce oluşturduğumuz listedeki verilerin satır numarasına göre atayacağız.

void m_Grid_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
{
   if (e.ColumnIndex == 0)
   {
        e.Value = m_Data[e.RowIndex].Id;
   }
   else if (e.ColumnIndex == 1)
   {
       e.Value = m_Data[e.RowIndex].Val;
   }
   else if (e.ColumnIndex == 2)
   {
        Random rnd = new Random();
        e.Value = rnd.Next(1, 10000000);
   }

}

Yukardaki satırlarda bişey dikkatinizi çekmiş olmalı. Son else if ifadesi içindeki satırlar.

Random rnd = new Random();
e.Value = rnd.Next(1, 10000000);

Burada bir Random nesnesi (rnd) oluşturup bu nesnenin Next() metodu ile verilen aralıkta rastgele bir değer elde ediyoruz. Bu değeri son sutunumuzdaki hücrelere eşitliyoruz.

CellValueNeeded olayı kaydırma çubuklarını hareket ettirip hücreleri görüntülemeye çalıştıtğımızda da meydana gelir.

En son olarak btnHucreSayisi adlı button umuzun Click olayındaki kodlara göz atalım. Burada gezilen satırlar birer birer sayılarak kaç satır olduğu ekrana MessageBox ile gösterilecektir. Programı çalıştırıp kaydırma çubuklarını en sona kadar hareket ettirdiğimizde göreceğiz ki 1000000 tane satır gezilmemiş.

Şimdi programımız çalıştıralım ve genel görünüme bakalım: 




Şimdi kaydırma çubuğunu en aşağı kadar indirelim ve “Hücre Sayısı” yazan button a tıklayalım. Şu şekilde bir ekranla karşılaşacağız:



Gördüğünüz gibi MessageBox ile gezilen yani görüntülenmeye çalışılan satır sayısını öğrendik. Son kaydımızda 1000000 gibi bir sayı yazmasına (0 dan başladığımız için 1000001. kayıt) rağmen bize gelen bilgi 197 gibi bir sayı (kaydırma hızınıza bağlı olarak değişir).

Burdan da anlaşılacağı gibi DataGridView de VirtualMode da çalışırken griddeki veriler sadece görüntülenmek istendiği zaman ekranda görüntülenir. Diğer satırlardaki veriler yoktur. Ne zaman kaydırma çubuğunu hareket ettirsek CellValueNeeded olayı meydana gelicek ve hücrelerdeki değerler gözükecektir. Biz de burada hücrelerdeki değerleri hesaplamak bu olayda yazdık.

Şimdi, eğer biz bu gridle VirtualMode çalışmamış olsaydık ne farkedicekti ? Öncelikle programınızı çalıştırdığınızda bir süre bekliyeceksiniz çünkü gridde büyük miktarda bir satır eklenecek ve bu satırlar için değerler oluşturalacaktır. Eğer VirtualMode da çalışmadan bir seferde bu değeri göstermeye çalışırsak ne kadar bekliyecektik ve veriler arasında nasıl bir gezinme rahatlığı olucaktı.

Bunun için DataGridView kontrolümüzün özelliklerinden VirtualMode özelliğini false yapıcağız. Daha sonra InitGrid() metodundaki son açıklama satırına kadar olan satırları inaktif etmek için açıklama satırı yapıp son açıklama satırını aktif yapın. Yani InitGrid() metodumuzda sadece aşağıdaki satır aktif olucak:

m_Grid.DataSource = m_Data;

Bu satırla m_Data koleksiyonumuzdaki verileri DataGridView e bind ettik ve bir seferde verileri göstermeye çalıştık.

Programızı çalıştıralım bakalım ne kadar bekliyeceğiz. Sisteminize bağlı olarak bu bekleme süresi değişecektir fakat şurda bir gerçek var ki ilk duruma göre çok daha uzun bekledik ve kaydırma çubuğuyla satırlar arasında hiç de rahat gezemedik.
İsterseniz şimdiki durumla ilk durum arasındaki hızı karşılaştırmak için zaman tutabilirsiniz.
Ben kendi sistemimde her iki durumdaki elde ettiğim zamanlar arsında
şöle bir sonuç çıktı:

VirtualMode durumunda :11 sn
Normal durumda              :1 dk 6 sn

Bu değerler program Debug edilmeye başladığından itibaren geçen sürelerdir. Gördüğünüz gibi iki durum arasında ne kadar önemli bir fark var. Ve satırlar arasında hiç de rahat gezinti olmadı. Sisteminize bağlı olarak bu değerler değişebilir. Fakat şu bir gerçek ki iki durum arasında performans olarak gözle gözükür bir fark olduğu....

Son olarak CellValueNeeded olayından biraz bahsetmek istiyorum. Programımızı ilk çalıştırdığımızda DataGridView deki değerlerden en son kolondaki hücrelere fareyle tıkladığımızda verilerin değiştiğini görüceksiniz. Peki neden böyle bişey oldu ?

Biz CellValueNeeded olayında son else if bloğunda restgele değerler oluşturarak bu değerleri son kolona atamıştık. Hücrelere tıkladığımız anda CellValueNeeded olayı tekrar tetiklenir bu yüzden yeniden rastgele bir değer hesaplanıcağından bu değerler değişecektir. Diğer kolonlarda böle bir durum olmayacaktır çünkü bu hücreler için değerleri baştan belirlemiştik. Fakat hücreler tıkladığımızda, bu hücrelerde de CellValueNeeded olayı tetiklenir.

Burada makeleme son verirken umut ediyorum okuyanlar için faydalı olur. Tekrar buluşmak dileğiyle...

Recep DABAN

Mail: [email protected]
Makale:
DataGridView Ile VirtualMode'da Çalışmak C#, Visual C# ve .NET Recep Daban
  • Yazılan Yorumlar
  • Yorum Yaz
ŞUB
21
2013
makalenizi birkaç kez okudum fakat kendi kodumda virtual modu yapmayı başaramadım. veri tabanından veriyi stored procedure ile çağırıyorum, dataGridView1.DataSource= veriyiCagir(urunID) tarzı datatable döndüren bir fonksiyon ile. burda hangi nesnenin hangi eventine ne yazacağım bilmiyorum. yardımcı olursanız çok sevinirim. teşekkürler şimdiden
KAS
20
2008
CPU nun bu kadar yoğun çalışması en son satırın açık olmasından kaynaklanabilir. m_Grid.DataSource = m_Data satırı verileri gride bind ediyor.. Onun için CPU ya bu kadar yüklenilmiş olabilir..
KAS
19
2008
makaledekileri yapmaua çalıştım ancak m_Grid.Rows.AddCopies(0, 1000000) satırında takıldı. burada cpu tavana vurdu 100% oldu. Neden böyle olduğunu anlamadım. 1000000 yerine 5000 yaptım yine aynı şey oldu. Bu neden kaynaklanabilir.
ARA
1
2007
makaleyi tam olarak okuyamadım ama database den çektiğim verileri select top yöntemi ile cache leyip virtual mode de kullandım. ancak fatura veya fiş gibi belgelerde hafızada çalışmak daha mantıklı hafızayı cache lemek de lazım. datagridview açısından örneğin 10.000 kayıtlık bir fişi gösterirken zorlanmaması için
Sayfalar : 1 
Yorum yazabilmek için üye girişi yapmalısınız. Üye girişi için tıklayın.
Üye değilseniz Üyel Ol linkine tıklayarak üyeliğinizi hemen başlatabilirisniz.
 
  • Bu Konuda Son 10
  • Eklenen Son 10
  • Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor