TemplateColumn ile Keyfi Sütunlar
DataGrid hakkındaki yeni bir makale ile tekrar birlikteyiz. Bu makalede konumuz TemplateColumn.. Önceki makalelerdeki gibi durumun vehametini anlatır paragraflarla giriş yapmak yerine, çok hoşunuza gideceğinden emin olduğum TemplateColumn 'un ne olduğunu, nasıl kullanıldığını anlatmayı öne almayı tercih ediyorum.
Önce TemplateColumn hakkında kısa bir ön bilgi verelim. DataGrid - 2 makalesinin de konusunu oluşturduğu gibi, bir DataGrid 'in AutoGenerateColumns özelliğine False değerini atayarak, veritabanından aldığımız tablonun hangi sütunlarının hangi sırayla gösterileceğine kendimiz karar verebiliyor, sütun başlıklarını kendimiz belirleyebiliyor, sütunun genişliğini, yatay/dikey hizalamasını keyfimizce seçebiliyoruz.
Peki ama, iki farklı alanın değerini aynı sütunda gösterebiliyor muyuz? BoundColumn kullanımı bize bu imkanı vermiyor. Ancak ASP.NET 'in gözdelerinden DataGrid kontrolü bu konuda farklı çözümler sunmakta gecikmiyor. Bu makelede inceleyeceğimiz TemplateColumn, BoundColumn ile edindiğimiz imkanların yanına yenilerini katıyor.
Örneğin; TemplateColumn 'un sunduğu yeni imkanlarla birlikte, içerisinde veritabanından alınan herhangi bir alanın değerinin bulunmadığı sütunlar oluşturabiliriz. DataGrid kontrolümüze laf olsun diye sütunlar ekleyebiliriz. Veya bu özelliği daha verimli bir şekilde kullanmak istersek, birden fazla alanın değerini aynı sütun içerisinde gösterebilir, hatta veritabanından aldığımız alanın değerini bir fonksiyona gönderebiliriz.
BoundColumn gibi TemplateColumn 'uda <Columns> etiketleri içerisine yazıyoruz. Hatırlatmak gerekirse, BoundColumn şu şekilde kullanılıyordu:
<asp:DataGrid id="dataGrid1" runat="server"
AutoGenerateColumns="False">
<Columns>
<BoundColumn HeaderText="Ogr. No" DataField="No"/>
<BoundColumn
HeaderText="İsim"
DataField="isim">
</BoundColumn>
</Columns>
</asp:DataGrid>
BoundColumn kullanımında eğer sütun için ItemStyle belirlenmeyecekse, kapama etiketi kullanmaksızın, etiket / işareti ile kapatılabiliyordu. ItemStyle kullanılacaksa, açma ve kapama etiketleri yazılıyor, etiket içinde HeaderText ile sütun başlığı, DataField ile ise alan ismi belirleniyordu.
TemplateColumn mantık olarak BoundColumn 'a benzerken, biraz daha fazla kod yazılmasına neden olur. Aynı şekilde TemplateColumn 'lar <Columns> etiketi içinde yazılırlar. TemplateColumn 'un açma ve kapama etiketleri arasında HeaderTemplate, ItemTemplate ve EditItemTemplate kullanılabilir. HeaderTemplate ile sütun başlığı, ItemTemplate ile sütunda gösterilecek değer, EditItemTemplate ile ise daha sonraki bir makalemizin konusu olacak olan DataGrid 'in düzenleme (editing) işlemi sırasında sütunda gösterilecek değer belirlenir. Editing özelliği olmaksınız EditItemTemplate kullanılmasına gerek yoktur.
Yukarıdaki paragraf kafanızda TemplateColumn 'a dair bir fikir oluşmasına neden olmuştur eminim, ancak bu özelliğin yazım şekli konuyu çok daha netleştirmeye yarayacak. Şimdi yukarıdaki DataGrid kontrolünde BoundColumn yerine TemplateColumn kullanalım:
<asp:DataGrid id="dataGrid1" runat="server"
AutoGenerateColumns="False">
<Columns>
<asp:TemplateColumn>
<HeaderTemplate>
Ogr.No.
</HeaderTemplate>
<ItemTemplate>
<%# Container.DataItem("no") %>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="İsim">
<ItemTemplate>
<%# Container.DataItem("isim") %>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
Gördüğünüz gibi TemplateColumn, BoundColumn 'un aksine başında asp: takısı taşıyor. HeaderTemplate kullanılabiliyor olmakla birlikte, istenirse açma asp:TemplateColumn etiketi içinde HeaderText özelliği ile de sütun başlığı belirlenebiliyor. ItemTemplate 'de kullandığımız <%# Container.DataItem("alan_adi") %> sentaksı, veritabanından alınan tablodan herhangi bir alanın sütun içinde gösterilmesi için tipik bir yoldur. Bu yol kullanılarak istenen alanlar, istenen şekillerde gösterilebilir. Pratikte, yukarıdaki iki kod aynı sonucu verirler.
Basit bir TemplateColumn kullanımı örneği gördüğümüze göre, bu yeni özelliğin faydalarından bir-iki tanesini deneyebiliriz. Biraz sonra yapacağımız örnekde, önceki DataGrid makalelerimde kullandığım kisiler.mdb veritabanının kisiler isimli tablosu yerine, yapmak istediklerime daha uygun şekilde dizayn ettiğim mesajlar isimli bir tablo kullanacağım. Bu tablonun mesaj_id isimli AutoNumber bir alanı, gonderen isimli Text türünde bir alanı, mesaj isimli memo türünde bir alanı, ve tarih isminde Date/Time türünde bir alanı var. tarih isimli alanın varsayılan değerini (Default Value) Now() olarak belirledim.
Örneğimizde, mesaj_id isimli alanın değerini göstermeyeceğiz. gonderen ve tarih isimli alanları tek bir sütun içerisinde, mesaj türünde alanı ise diğer bir sütun içerisinde göstereceğiz. TemplateColumn kullanımı sayesinde verileri farklı işlemlere tabi tutarak gösterebileceğimize örnek olsun diyerekten, tarih ve mesaj isimli alanları formatlayarak göstereceğiz.
<%@ Page Language="VB" Debug="true" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.OleDb" %>
<script language="VB" Debug="true" runat="server">
Sub Page_Load(Source As Object, E As EventArgs)
If Not IsPostBack Then
bindDataGrid
End If
End Sub
Sub bindDataGrid()
Dim connstr As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath("kisiler.mdb") + ""
Dim sql As String = "SELECT * FROM mesajlar"
Dim conn As New OleDbConnection(connstr)
conn.Open()
Dim adapter As New OleDbDataAdapter(sql,conn)
Dim ds As New Dataset()
adapter.Fill(ds,"mesajlar")
dataGrid1.DataSource = ds.Tables("mesajlar")
dataGrid1.DataBind()
conn.Close()
End Sub
</script>
<html><head></head><body><form runat="server">
<asp:DataGrid runat="server" id="dataGrid1"
AutoGenerateColumns="False"
BorderWidth="1px" BorderStyle="Solid"
CellPadding="2" CellSpacing="0"
BorderColor="#C7C7C7"
Font-Name="Verdana" Font-Size="8pt">
<HeaderStyle BackColor="#EAEAEA" HorizontalAlign="Center" Font-Bold="True"/>
<ItemStyle BackColor="#E1F0FF"/>
<AlternatingItemStyle BackColor="#D2E9FF"/>
<Columns>
<asp:TemplateColumn>
<ItemStyle HorizontalAlign="Center" width="100"/>
<HeaderTemplate>
GÖNDEREN
</HeaderTemplate>
<ItemTemplate>
<b><%# Container.DataItem("gonderen") %></b>
<br>
<i><%# CType(Container.DataItem("tarih"),DateTime).ToString("dd-MMMM-yy HH:mm") %></i>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn>
<ItemStyle VerticalAlign="Top"/>
<HeaderTemplate>
MESAJ
</HeaderTemplate>
<ItemTemplate>
<div style="width:300;">
<%# Replace(Container.DataItem("mesaj"),VbCrLf,"<br>") %>
</div>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
</form></body></html>
Bu uzun kod içerisinde kullandıklarımı teker teker anlatmayacağım. Onun yerine ItemTemplate 'lere ve asp:TemplateColumn 'lar içinde kullandığım ItemStyle 'lara değineceğim.
DataGrid kontrolümüzün iki sütunu var. AutoGenerateColumns özelliğine False değerini atayarak, iki sütunun formatını da TemplateColumn ile belirliyoruz. İki sütun içinde HeaderTemplate etiketinden önce ItemStyle kullanıp, sütunun yatay hizalamasını ve genişliğini yazıyoruz. GÖNDEREN başlıklı birinci sütunun ItemTemplate 'inde, yalın <%# Container.DataItem("alan_adi") %> sentaksıyla gonderen isimli alanı gösterirken, bir satır boşluk verdikten sonra tarih isimli alanı farklı bir formatta gösteriyoruz.
tarih isimli alanı formatlarken kullandığım CType fonksiyonu, bir değerin türünü başka bir türe değiştirmek için kullanılır. İlk parametre olarak dönüştürülecek değişken/değer yazılırken, ikinci parametre olarak sonuç tür yazılır. Dönüştürme (CType) işleminden sonra DateTime formatına dönmüş olan tarih bilgisinin, ToString metoduna verdiğimiz parametreler ile tarih bilgisini farklı bir formatta gösteriyoruz.
dd anahtarı ile çift haneli günü rakam halinde, MMMM anahtarı ile uzun haliyle ay ismini metin halinde, yy anahtarı ile yılı son iki hanesiyle, HH ve mm anahtarları ile ise saati saat/dakika formatıyla gösteriyoruz.
İkinci sütunumuzda ise, veritabanındaki türü memo olan mesaj isimli alanı gösterirken, alanın değeri içindeki VbCrLf karakterlerini <br> karakterleri ile Replace fonksiyonunu kullanarak değiştiriyoruz. Bu iki formatlama yöntemine benzer şekillerde, ItemTemplate içinde farklı fonksiyonlar kullanabilir, alanların değerlerini kendi yazacağınız fonksiyonlara gönderip sayfanızda daha değişik sonuçlar gösterebilirsiniz.
Örneğin, tarih bilgisini benim gösterdiğim şekilde formatlamak yerine, kendi yazacağınız bir fonksiyona gönderebilir, fonksiyona aldığınız tarih bilgisini birkaç if..else if..end if kontrolüne tabi tutarak "bugün", "dün" veya "önceki gün" e ait olup olmadığını öğrenebilirsiniz. Yeni bir makalede görüşmek üzere.. Kolay gelsin..
