// ** "Kaan Aslan" C# Ders Notu www.csystem.org
Veri bağlama (DataBinding) mekanizması
Veri bağlama bir kontrolün bir veri kaynağı ile ilişkilendirmesi ve otomatik olarak o veri kaynağındaki istenilen elemanı görüntülemesi anlamına gelir. Veri kaynağındaki bilgi değiştiği zaman kontrolde görüntülenen bilgi de değişecektir. Veri bağlama işleminde bir kontrol ve bir veri kaynağı söz konusudur. Teknik olarak Ilist, IbindingList arayüzlerini destekleyen sınıflara veri kaynağı denmektedir.
Veri bağlama işlemi basit ve karmaşık olmak üzere iki guruba ayrılabilir. Eğer veri kaynağı tek bir bilgi içeriyor ise basit bir bağlama söz konusudur. Eğer kontrol tek bir elemanı görüntülüyorsa bu bağlama işlemi basit. Birden fazla elemanı görüntüleyebiliyorsa bu bağlama işlemi karmaşıktır.
Karmaşık bağlama işlemleri
ListBox, ComboBox, DataGridView gibi kontrollerde yapılan bağlama işlemleri bu kontrol sınıfların DataSource ve DisplayMember elemanları ile ilişkilidir. Eğer bu kontrol sınıflarının DataSource elemanına (Object türündendir) bir veri kaynağının referansı atanırsa bu kontroller o veri tabanına bağlanmış olur. DisplayMember elemanı veri kaynağının hangi elemanının görüntüleneceğini belirler. Display member string türündendir ve eğer gerekmiyorsa bu elemana atama yapılmayabilir.
Bir dizi, ArrayList gibi Collectionlar Ilist arayüzünü destekledikleri için karmaşık veri bağlamada kullanılabilirler. Yada örneğin bir DataTable nesnesinin sütunu veri bağlamada kullanılabilir. Örneğin:
int[] a = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
listBox1.DataSource = a;
Burada DisplayMember elemanının kullanılmasına gerek kalmamıştır. Bu işlem adeta dizinin içerisindeki bu int değerlerin ListBox1.Items.Add fonksiyonu ile listeleme kutusuna eklenmesi ile eşdeğerdir. Yani artık listeleme kutusunun items Collectionunda bu int değerler vardır. Aynı işlem ArrayList sınıfı ile de yapılabilirdi.
ArrayList m_a = new ArrayList();
for (int i = 0; i < 100; ++i)
m_a.Add(i);
listBox1.DataSource = m_a;
DisplayMember elemanı veri kaynağında saklanan nesnelerin bir property ismi olarak girilebilir. Bu durumda kontrole yine Collection içerisindeki elemanlar yerleştirilir fakat kontrol Collection içerisindeki nesnelerin ilgili property elemanlarını görüntüler. Örneğin:
ArrayList m_a = new ArrayList();
for (int i = 0; i < 100; ++i)
m_a.Add(i.ToString());
listBox1.DataSource = m_a;
listBox1.DisplayMember = "Length";
Burada listeleme kutusunda string nesneleri yerleştirilmiştir fakat onların Length propertyleri gösterilmiştir. Bağlama işlemi için veri kaynağı bir DataSet yada DataTable de olabilir. Örneğin:
listBox1.DataSource = m_dt;
listBox1.DisplayMember = "Name";
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
namespace SampleDataBinding
{
public partial class Form1 : Form
{
private CurrencyManager m_cm;
private DataTable m_dt;
public Form1()
{
InitializeComponent();
m_dt = new DataTable("Info");
m_dt.Columns.AddRange(new DataColumn[] { new DataColumn("Name", typeof(string)), new DataColumn("No", typeof(int)) });
DataRow dr;
dr = m_dt.NewRow();
dr["Name"] = "Kaan Aslan";
dr["No"] = 123;
m_dt.Rows.Add(dr);
dr = m_dt.NewRow();
dr["Name"] = "Ali Serçe";
dr["No"] = 435;
m_dt.Rows.Add(dr);
dr = m_dt.NewRow();
dr["Name"] = "Necati Ergin";
dr["No"] = 763;
m_dt.Rows.Add(dr);
dr = m_dt.NewRow();
dr["Name"] = "Serdar Basokutan";
dr["No"] = 826;
m_dt.Rows.Add(dr);
listBox1.DataSource = m_dt;
listBox1.DisplayMember = "Name";
m_cm = (CurrencyManager)this.BindingContext[m_dt];
}
private void button1_Click(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
++m_cm.Position;
}
private void button3_Click(object sender, EventArgs e)
{
--m_cm.Position;
}
}
}
Bir kontrol bir veri kaynağına bağlandığı zaman veri kaynağındaki bir eleman aktif eleman olur, kontrol bu aktif elemanı gösterir. Örneğin biz bir diziyi listeleme kutusuna bağladığımızda listeleme kutusundaki aktif eleman (yani seçilmiş eleman) henüz ilk elemandır. İşte veri bağlama konusu ile ilişkili bir mekanizma yolu ile aktif eleman değiştirilerek bir gezinme (Navigation) sağlanabilir.
Bir veri kaynağına bağlantı yapıldığında bağlantı yapılan kontrolün ilişkin olduğu form sınıfının BindingContext isimli Collection elemanına yeni bir eleman eklenir. BindingContext elemanına her veri kaynağı için ekleme yapılmaktadır. Örneğin bir veri kaynağı üç ayrı kontrole bağlanmış olsun, form sınıfının BindingContext collection elemanına üç değil yalnızca bir eleman eklenmiş olacaktır çünkü tek bir veri kaynağı için bağlama yapılmıştır. Form sınıfının BindingConext isimli Collection property elemanı BindingManagerBase sınıfı türünden nesneleri tutmaktadır.
public override BindingContext BindingContext {get; set;}
BindingManagerBase sınıfı Abstract bir sınıftır, bu sınıftan CurrencyManager ve PropertyManager sınıfları türetilmiştir. Dolaşımı sağlayan sınıf CurrencyManager sınıfıdır. BindingContext sınıfının object parametreli indexleyicisi ilgili veri kaynağı için dolaşımı sağlayan CurrencyManager nesnesini verir. Bu indexleyici bize nesneyi taban sınıf olan BindingManagerBase türünden verir. Yani CurrencyManager sınıfına tür dönüştürmesi yapılması gerekir.
CurrencyManeger sınıfının en önemli elemanı int türden Position propertysidir. Bu elemana bir index değeri atanır ve böylece veri kaynağına bağlanmış olan kontroller aktif olarak o indexteki elemanı gösterir. Konuyu özetlemek gerekirse şunlar söylenebilir:
1. Veri kaynağını temsil eden nesnenin referansı ds olsun. Biz bu veri kaynağını çeşitli kontrollere bağlamış olalım. Bu işlemin sonucunda Framework form sınıfının BindingContext Collection elemanına bir CurrencyManager nesnesi ekler.
2. Oluşturulan CurrencyManager nesnesi programcı tarafından form sınıfının BindingContext elemanından alınarak sınıfın bir veri elemanına çekilebilir. Örneğin:
private CurrencyManager m_cm;
//...
m_cm = (CurrencyManager) this.BindingContext[ds];
3. Artı kelde edilen CurrencyManager nesnesinin position propertysi ile gezinti yapılabilir. Örneğin Next düğmesine basıldığında ++ m_cm.Position; işlemi Prev düğmesine basıldığında -- m_cm.Position; işlemi yapılabilir.
Uğur
-------------------------------------------------------------------------------------------------------------
Hayat bir bisiklete binmek gibidir. Pedalı çevirmeye devam ettiğiniz sürece düşmezsiniz. Claude Peppeer
Kusuru söylenmeyen adam, ayıbını hüner sanır. Türk Atasözü