Aklımda Kalası Kelimeler

* давайте работать вместе
* Zarf ve Mazruf, Zerafet(xHoyratlık) ile aynı kökten(za-ra-fe) gelir
* Bedesten
* Suç subuta ermiştir - Suç sabit olmuştur

13 Aralık 2007 Perşembe

GridView DataTable InstantiateIn TemplateColumn Itemplate

Dinamik TemplateColumn için bir örnek(Bu kez çeviri değil)

Herşeyden önce GridView ın aspx ve cs sayfalarındaki durumlarını incelemenizi tavsiye ederim. Biz biraz bakalım ve esas konumuza adım adım ilerleyelim.
Öncelikle GridView sınıfından bir örneği sayfamıza sürükler
<asp:GridView ID="GridView1" runat="server" />

Tabii bu tagın arasına eklenecek çok şey var, bunlardan bir kısmı ekleyeceğim.
Örneğin: AutoGenerateColumns="false"
Ama ben GridView anlatacak değilim, size faydası dokunacak genelde gözden kaçan bir kaç şeyden bahsedeğim.
  • Örneğin: DataKeyNames="ProductID"... DataKeyNames bizim için Kayıt Silme, Düzenleme işlemleri için tablomuzdaki Primary Key alanımızdır.Bu alan tablomuzda hangi satırın silineceğini veya güncelleneceğini diğer satırlarla(tablodaki kayıtlarla) karışmadan gösterecektir.
  • Columns ile GridView içindeki göstermek istediğimiz tüm alanları görüntüleyeceğiz.
  • TemplateField, ile kolonu eğer Edit ya da düz haliyle görüntülemek istediğimizde hangi bileşenleri kullanacaksak burada her kolon için bir TemplateField oluşturup içine ItemTemplate ve EditItemTemplate leri yerleştiriyoruz.
  • ItemTemplate ile verimizi göstereceğimiz kolonumuzu hangi bileşenlerle görüntüleyeceksek bu bileşenleri içerir.
  • EditItemTemplate ile verimizi editleyeceğimiz kolonumuzu hangi bileşenlerle görüntüleyeceksek bu bileşenleri içerir.
  • BoundField ile de hiç template arasına almayıp label içinde görüntüleyeceğimiz alanlarımızı gösteriyoruz.

<Columns>

<asp:TemplateField HeaderText="RowIndex">

<ItemTemplate>
<asp:Label ID="lblRowIndex" runat="server" Text='<%# Bind("tel1") %>' />
</ItemTemplate>

<EditItemTemplate>
<asp:TextBox ID="lblRowIndex" runat="server" Text='<%# Bind("tel1") %>' />
</EditItemTemplate>

</asp:TemplateField>

<asp:BoundField HeaderText="Name" DataField="Name" />
<asp:BoundField HeaderText="ListPrice" DataField="ListPrice" />
<asp:BoundField HeaderText="SellStartDate" DataField="SellStartDate" />

</Columns>


Buraya kadar küçük bir özette yapmış olduk.Şimdi Dinamik TemplateColumn oluşturma işine bakalım.
İhtiyaçlarımız:
Bir adet DataTable (DataSource olarak kullanacağız)
Bir adet GridView
Bir adet ITemplate interface ini referans alan TemplateColumn sınıfı

Şimdi bunları neden ve nasıl biraraya getireceğiz sorularını cevaplayalım.
  1. DataTable sınıfından bir nesne türeteceğiz ve içine bir kaç satır veri ekleyeceğiz.Çünkü sayfamıza yerşeştirdiğimiz GridView için DataSource olacak bu tablo.
  2. Sayfamızdaki GridView verilerimi gösterdiğimiz düzenlediğimiz nesnemiz olacak.İki template şablonumuz olacak GridView içinde çalışma zamanında üretilen:
    1. Birisi, sayfa ekrana gelir gelmez verileri Label lar içinde gösteren,
    2. diğeride Edit düğmesine basılması halinde TextBox içerisinde gösteren.
Şimdi DataTable nesnemizi tüm page içerisinde erişilen bilen bir değişken olarak tanımlayalım:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
 
public partial class _Default : System.Web.UI.Page 
{
    DataTable dt = new DataTable();


Bir de bu DataTable içini doldurmamız gerekecek.Bunun için bir fonksiyon yazalım:
    public void dtBuild()
    {
        DataColumn dc_1 = new DataColumn( "isim" );
        DataColumn dc_2 = new DataColumn( "meslek" );
        dt.Columns.Add( dc_1 );
        dt.Columns.Add( dc_2 );
 
        DataRow dr = dt.NewRow();
        dr["isim"] = "Cem";
        dr["meslek"] = "2";
        dt.Rows.Add( dr );
        DataRow dr1 = dt.NewRow();
        dr1["isim"] = "Cenk";
        dr1["meslek"] = "1";
        dt.Rows.Add( dr1 );
        DataRow dr2 = dt.NewRow();
        dr2["isim"] = "Cengo";
        dr2["meslek"] = "3";
        dt.Rows.Add( dr2 );
    }

Şimdiii, sayfamız ekrana ilk geldiğinde GridView1 nesnemizin dt ile dolması ve kolonları kendi otomatik üretsin diye, AutoGenerateColumns özelliğini TRUE yapacağız ama editlendiğinde FALSE olacak ki biz TemplateColumn özelliği ile sütunlarımızı değiştirebilelim. O halde Page_Load metodumuza bir bakalım:
    protected void Page_Load( object sender, EventArgs e )
    {
        if ( !IsPostBack )
        {
            dtBuild();
            GridView1.AutoGenerateColumns = true;
            GridView1.DataSource = dt;
            GridView1.DataBind();
        }
        else
        {
            GridView1.AutoGenerateColumns = false;
        }
    }


Bu da güzel oldu.Yukarıyı anlatmak gerekirse, dtBuild() fonksiyonu ile DataTable sınıfından türettiğimiz dt nesnemizin içini satırlarla dolduruyoruz.

GridView1.AutoGenerateColumns = true;
ile de dt içindeki kolonları otomatik olarak türetmesini istiyoruz.Bunu ileride yine TemplateColumn larla değiştireceğiz.

GridView1.DataSource = dt;
GridView1.DataBind();
Burada GridView1 nesnemizin DataSource özelliğini dt nesnemize atıyor ve verileri göstermek için DataBind() metodunu çalıştırıyoruz.

E bu da güzel. Şimdi biz Edit lemeye(düzenlemeye geçelim).

11 Aralık 2007 Salı

DataGrid e kod ile TEMPLATECOLUMN eklemek

Bu aslında hafif bir çeviri olacak.Ama önemli ve geyik olmayan yerler için zamanım var.
Adresimiz: http://www.tek-tips.com/faqs.cfm?fid=4868

ITemplate Interface Hakkında...

Template kolonu çalışma zamanında oluşturmak çok kolaydır. Genel şekli aşağıdaki gibidir:
------------------
TemplateColumn tc = new TemplateColumn();
tc.HeaderText = [Text of column header];
tc.ItemTemplate = [ITemplate type];
// dg is the DataGrid control
dg.Columns.Add(tc);
------------------

Yukarıda da gördüğünüz gibi, basitçe TemplateColumn değişkeni üretebilir, Text ve ItemTemplate özelliklerini verebiliriz.Devam edelim.Önemli kısmı ItemTemplate özelliğidir. Gördğünüz gibi bir sınıf tanımlamalı ItemTemplate Interface inden türeyen.Böylece template column u üretip gride eklemek mümkün olacaktır.Thus, adding a template column to a grid at run time will consist of creating a class that implements the ITemplate interface. Bu sınıfın nasıl olduğunu şimdi göreceğiz.

Şimdi, ITempalte interface'nin sadece bir tane metodu vardır, InstantieateIn adında.Bu metod yeni bir örnek template kolon üretildiğinde çalışacaktır.System.Web.UI.Control tipinde bir parametre alır . Böylece bu metodu ile örneklediğiniz nesneyi oluşturduğunuz yerde template column create olmuş olur.(cümle berbat oldu ama idare edin). Benim durumumda bir check box a ihtiyacım olacak template columnun içinde ve sınıfım şöyle görünecek:

private class CheckBoxTemplate : ITemplate
{
// Implementation of ITemplate
public void InstantiateIn(System.Web.UI.Control container)
{
// Create a check box
CheckBox cb = new CheckBox();
// Make the check box appear in the column
container.Controls.Add(cb);
}
}


Hepsi bu! Bu template column oluşturmak için ihtiyacınız olan kod. Düşündüğünüz gibi, sizde text box ın özelliklerini set ettiğiniz gibi her ne kontrol oluşturuyorsanız template column içinde, onunda özelliklerini dilediğiniz gibi set edebilirsiniz. Yanı sıra, sadece bir kontrol kullanmaklada sınırlı değilsiniz. Dilediğiniz sayıda Template Column içine nesneler create edebilirsiniz(create etmek ne demekse) ...


Data Biding (veri bağlama)
Fakat hepsi bu değil! InstantiateIn metodu içinde veri çekmek ve kontrolonüze bağlamak mümkün. Veri bağlamayı uyarlamak, create ettiğiniz kontrolünüzün DataBinding olayına kod yazmakla mümkün olacak. Event handling(olaylarla başa çıkma) mekanizması Web ve Windows formlarındakiyle aynıdır: Bir metod create edersiniz aynı olayın temsilcisinin imzasıyla(isaretiyle) ve sonra temsilciye metodu eklersiniz. Sınıfınızın son hali kalın kısımla gösterilmiş:
[Yani diyorki bir metodu oluşturup DataBinding metoduymuş gibi sınıfınıza eklersiz. İşte yeni metodunuz,BindCheckBox ve bunu DataBinding işlemi halinde çalışması için sınıfınıza ekliyorsunuz...]

CODE

private class CheckBoxTemplate : ITemplate
{
public void InstantiateIn(System.Web.UI.Control
container)
{
// Create a check box
CheckBox cb = new CheckBox();
//Attach method to delegate
cb.DataBinding += new System.EventHandler(this.BindCheckBox);
container.Controls.Add(cb);
}

//Method that responds to the
DataBinding event

private void BindCheckBox(object sender, System.EventArgs e)
{
CheckBox cb = (CheckBox)sender;
DataGridItem container = (DataGridItem)cb.NamingContainer;
cb.Checked = [Data binding expression];
}
}
Gördüğünüz gibi, InstantiateIn metoduna yeni bir satır kod eklendi:

cb.DataBinding += new System.EventHandler(this.BindCheckBox);

Tüm bu eklemeler checkbox kontrolümüzün DataBinding event ında BindCheckBox methodunu çalıştırmak içindi. DataBinding event temsilcisinin iki parametresi vardır: object tipinde sender, ve EventArgs tipinde e,(Gerçekten bir databinding e ihtiyacımız yok). sender, harektin başladığı check box nesnesini gösterir , ve bu yüzden aşağıdaki koda ihtiyacımız vardır:

CheckBox cb = (CheckBox)sender;

Basitçe CheckBox gibi bir referansı getirir. Şimdi check boxın NamingContainer özelliği CheckBox kontrolünün olduğu DataGridItem(diğer bir değişle, satır(row)) u gösterir. Böylece Böylece aşağıdaki satırda grid içinde CheckBox ın olduğu satıra ulaşabiliriz:

DataGridItem container = (DataGridItem)cb.NamingContainer;

Sonuçta, &quot;ItemID&quot; adında bir veri kaynağından çektiği veriyi gösteren bir DataGrid imiz olduğunu farzedersek, veri bağlama ifadesini DataBinder.Eval metodunu kullanarak yazabiliriz. Aşağıdaki satırda(yukarıdaki kod olmayan) CheckBox ın Checked özelliğini, eper "ItemId" veri kaynağında 10 ise True olarak set edecektir.


cb.Checked = (DataBinder.Eval(container.DataItem, "ItemID").ToString() == "10";);

Bu durumda Eval metodunun ne olduğunu bilmiyorsunuz.DataGridItem(DataGrid içinde bir row demektir DataGridItem) içerisinde row içerisindeki bir alanın değerini, object tipinde döndüren bir metoddur. Elbette verilerinizi bağlayan ifadeniz daha karmaşık olabilir.Bu metodda dilediğiniz şeyi yapabilirsiniz...

Son olarak kalın ile yazılmış hali ile ItemTemplate inizi Template Column kısmına ekleyebilirsiniz.

TemplateColumn tc = new TemplateColumn();
tc.HeaderText = [Text of column header];
//Isn't this beautiful?
tc.ItemTemplate = new CheckBoxTemplate();
// dg is the DataGrid control
dg.Columns.Add(tc);

Cool, eh?