25 Şubat 2011 Cuma

Nested (İçiçe) DataList

Web uygulamalarında veri gösterme kontrollerinden daha önce bahsetmiştik. Veritabanından, xml'den ...vs. bilgiler geldiği zaman, bu bilgileri, bahsettiğimiz veri gösterme kontrollerinden gösteriyoruz. DataList, GridView, Repeater vs. kullanıyoruz. Çoğu zaman tek bir kontrolle tüm bu bilgileri gösterebiliyoruz.


Senaryomuz gereği, bir kullanıcı birden fazla eğitim bilgilerine sahipse, ve bu eğitim bilgileri database'den birden fazla satır halinde geliyorsa, ne yapmamız gerekir?


İşte burada yardımımıza nested datalist giriyor. DataList içindeki ItemTemplate'ine bir datalist daha oluşturursak, her eğitim bilgisi için, ikinci yazdığımız DataList çalışacak ve biz eğitim bilgilerini datasource olarak verdiğimiz taktirde, her itemtemplate'de datalist çalışacak ve eğitim bilgileri birden fazla da olsa gösterilecek.


Kodlamaya gelirsek, ana düşüncemiz, dışardaki DataList için bir kaynak vermek olmalı ve daha sonra da ItemDataBound isimli eventini tetiklemek olmalı. Peki ne işe yarıyor bu event? ItemDataBound eventi, verileri ekrana yazmadan onlara erişmemizi sağlayan, bir takım işlemleri yapmamıza olanak sağlayan eventtir. Örneğin labellardan bazılarının visible'ını false yapmak. Veya kendi örneğimizden içerdeki diğer datalist'lere erişip, onlara datasource vererek çalışmalarını sağlamak vs..


Önce PageLoad'da en dıştaki DataList'imize veri kaynağı gösterelim.


public partial class _Default : System.Web.UI.Page
{
   if (!IsPostBack)
       {
    a = 0;
    id = Request.QueryString["UserID"].ToString();
    string query = "select * from XTable";
    DataTable dt = VerTabanından dönen sonuç
    dlResult.DataSource = dt;
    dlResult.DataBind();
        }
 }


protected void dlResult_ItemDataBound(object sender, DataListItemEventArgs e)
{       
   if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
   DataList dlPersonal =(DataList)e.Item.FindControl("dlPersonal");
   DataList dlEducation =(DataList)e.Item.FindControl("dlEducation");
   DataList dlJobExp = (DataList)e.Item.FindControl("dlJobExp");

   dlPersonal.DataSource = Verikaynağı 1
   dlEducation.DataSource = Verikaynağı 2
   dlJobExp.DataSource = Verikaynağı 3
   dlJobExp.DataBind();
   dlEducation.DataBind();
   dlPersonal.DataBind();           
}
}

Yukarıdaki kodlarda açıklama yapmak gerekirse, dlResult_ItemDataBound eventi, tam dlResult.DataBind() çalıştıktan sonra tetiklenir. Eventin içerisine girdiğimizde, bir kontrol yapmamız gerekir. Bu kontrol, DataList'in içinde footer,header,seperator,item, ve alternating template bulunduğundan, her bir template için bir kere çalışacaktır bu event. Dolayısıyla bizim, sadece item template ve alternating template için çalışmasını istediğimizden bu kontrolü koyuyoruz. Daha sonra bu DataList içindeki DataList'lere erişmek için FindControl metodu yardımıyla DataListlerimize erişip, onlara datasourcelarını veriyoruz. Ben burada, DataList içerisindeki labelların text'lerini Eval yardımıyla doldurdum, istersek içerdeki DataListlerin de ItemDataBound eventini tetikleyip, o datalistlerin içindeki labelları bulup, text'lerini değiştirebilirdik. Eval daha kısa ve mantıklı kullanış olacaktır.


Buradaki senaryo, DataList üzerinden gerçekleşti fakat, aynı event, aynı mantık GridView ve repeater için de geçerli. Sadece ufak birkaç kod değişikliği olacaktır. Onlar da kontrollere erişme kısmında olacaktır. Önemli olan mantığı oturtmak ki, bu örnekteki düşünce yapısıyla rahatlıkla yapılacaktır. 

0 yorum: