|
DataGridView Ile VirtualMode'da Çalışmak |
|
Gönderiliyor lütfen bekleyin... |
|
|
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
|
|
|
-
-
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
|
|