Makale Özeti

Yeni programlama modeli ile artık bir görsel geliştirme ortamı olan ASP.NET sunucu kontrolleri ile bu sıfatı hakettiğini gösteriyor

Makale

ASP.NET Sunucu Kontrolleri

Gökhan Altınören

gokhan@altinoren.com

 

Windows için yazılım geliştirmek her zaman zevkli olmuştur, ne de olsa elinizin altında Visual Basic gibi becerikli ve hızlı bir araç ya da Visual C++ gibi güçlü ve detaylı bir platform vardır. Microsoft da yeni araçlar, SDK’lar ve mükemmel dökümantasyon ile her zaman yazılımcının yanındadır.

 

Web tabanlı yazılım geliştirmeye gelince işler biraz değişir. Her ne kadar dökümantasyon olarak yeterli olsa da, ilk göz ağrımız ASP ile yazılım geliştirmek biz yazılımcılar için o kadar da kolay değildir. Notepad dışında standart bir IDE yoktur. Yazdığınız kodu HTML’in içinden ayıklamak işkence gibi gelir. Hata yaptığınızda kodunuzu ‘debug’ etmek bir derttir. Kodunuzu tekrar kullanmak zordur ve bu liste uzayıp gider.

 

Daha doğrusu giderdi. ASP.NET ile birlikte kötü günler geride kaldı dersek pek de yanlış yapmış sayılmayız. Artık Visual Studio .NET ortamında (ya da ücretsiz Web Matrix’i kullanarak) VB.NET ya da C#.NET ile eskiden “keşke ASP’de de olsa” dediğimiz bütün araçlar ve dil özelliklerini kullanarak harikalar yaratmak için önümüzde hiç bir engel kalmamış gibi gözüküyor.

 

Bu yazıda, Visual Studio .Net ortamında C# kullanarak bir sunucu kontrolünü nasıl yazabileceğimizi inceleyeceğiz. Yeri geldiğinde nesne yönelimli programlamayla ilgili bilgiler de vereceğiz. Okuyucunun .Net ortamı hakkında temel bilgiye sahip olması, örneğin anlaşılması için yeterli olacaktır. İngilizce terimleri olabildiğince türkçe karşılıklarıyla birlikte vermeye çalıştım, terminolojide yapmış olabileceğim hatalar için şimdiden özür diliyorum.

 

Nedir şu kontrol dedikleri?

 

Metin Kutusu:  

Şekil 1
Yazılımcıların yazdıkları kodu tekrar kullanması ya da başkaları tarafından yazılmış kodları kendi yazılımlarına eklemeleri için çok güzel bir çözüm olan ActiveX kontrolleri hepimiz biliyoruz. Aynı çözüm, ASP.NET için yazılım geliştirirken karşımıza kullanıcı kontrolleri (user controls) ve sunucu kontrolleri (server controls) olarak karşımıza çıkıyor. Kullanıcı kontrolleri ile ilgili bu sitede yer alan çok güzel makalelerden bilgi alabilirsiniz. Biz şimdi konumuz olan sunucu kontrollerine odaklanalım.

 

Visual Studio .NET ile birlikte, web tabanlı yazılım geliştirirken bize yardımcı olacak bir çok kontrol geliyor (Şekil 1). Eskiden veritabanından gelen kayıtları sayfada gösterebilmek için tekrar tekrar döngüler kurar, <tr> ve <td>’ler arasında kaybolurduk. Artık çok daha güzel ve fonksiyonel veri tablolarını DataGrid kontrolünü kullanarak çok daha kısa zamanda oluşturabiliyoruz. Tek satır kod yazmadan kullanabileceğimiz kullanışlı bir takvim (Calendar) kontrolümüz var. Veri girişi sırasında gerekli alanların doldurulup doldurulmadığını hem istemci hem de sunucu tarafında kontrol edebiliyoruz (RequiredfieldValidator, CompareValidator vs.)

 

Peki ama, tam da istediğimizi yapan bir kontrol yoksa ne yapmalıyız? İşte bu noktada Microsoft bize kendi kontrollerimizi yazma imkanını sunuyor.

 

YeniPencere kontrolü

 

HTML kullanarak bir link’i yeni pencerede şu şekilde açarız:

 

<a href="yenisayfa.htm" target="_blank">Yeni sayfa aç</a>

 

Aynı şeyi ASP.NET’in Hyperlink kontrolünü kullanarak yapalım:

 

<asp:HyperLink id="HyperLink1" runat="server"

NavigateUrl="yenisayfa.htm" Target="_blank">Yeni sayfa aç

</asp:HyperLink>

 

HTML ve JavaScript’i beraber kullanarak yeni açılacak pencerenin özelliklerini de belirtebiliriz. Örneğin, yeni pencerenin boyutlarını da belirlemek için:

 

<a href="yenisayfa.htm" target="_blank"

onclick="javascript:window.open(yenisayfa.htm,

pencere_adi,height=80,width=60);

return false;">Yeni sayfa aç</a>

 

Yine aynı şeyi ASP.NET kullanarak yapmak istersek... kendi kontrolümüzü yazmamız lazım. Hemen başlayalım.

 

Visual Studio .NET’i açıp File / New’den Project...’i seçelim. Visual C# Projects / Web Control Library’i seçip yeni projemize YeniPencere ismini verip OK’e klikleyelim (Şekil 2).

 

(Aynı işlem Visual Basic ile de yapılabilir. Bu makalede C# kullanıyoruz ama verilen kodlar Visual Basic’deki karşılıkları neredeyse aynıdır.)

 

 

(Şekil 2)

 

Öncelikle Visual Studio’nun bizim için yarattığı projeyi inceleyelim. Eğer kapalıysa, View’den Solution Explorer’ı açalım. Burada görülen AssemblyInfo.cs dosyası, kodumuz derlendiğinde oluşturulacak assembly’nin özelliklerini (versiyon numarası, telif bilgileri vs.) belirler. Bu bir deneme projesi olduğu için bu dosyayla ilgilenmeyeceğiz.

 

WebCustomControl1.cs dosyası, kullanabilmemiz için basit bir şablon kod içerir. Biz kendi kodumuzu adım adım oluşturmak istediğimiz için bu dosyayı üzerine sağ klikleyip Delete’i seçerek projemizden silebiliriz.

 

File / Add New Item... yapıp projemize YeniPencere.cs isimli yeni bir Class ekleyelim. Oluşturduğumuz class’ın üst kısmında referans namespace olarak sadece System olacaktır. Buraya şunları ekleyelim:

 

using System;

using System.ComponentModel;

using System.Drawing;

using System.Text;

using System.Web.UI;

using System.Web.UI.WebControls;

 

  • ComponentModel: Bir kontrol için gereken temel class’lar, arayüzler (interface), özellikler (attribute) vs.
  • Drawing: Kontrolümüze daha sonra toolbox’da kullanmak üzere resim eklemek için gerekli namespace.
  • Text: String manipülasyonu için gerekli namespace.
  • Web.UI: Kontrolümüzün kullanıcı arabiriminin bir parçası (UI element) olabilmasi için gerekli namespace.
  • Web.UI.WebControls: Kontrolümüzü üzerine inşa edeceğimiz (kalıtım / inheritence) HyperLink kontrolünün bulunduğu namespace.

 

Namespace ve class tanımlamamızı da şöyle değiştirelim:

 

namespace YazGelistir

{

     public class YeniPencere: HyperLink

     {

           public YeniPencere(): base()

           {

           }

     }

}

 

Öncelikle, şu andan itibaren kontrolümüze Visual Studio .Net üzerinde herhangi bir dilde programatik olarak erişmek için onu YazGelistir.YeniPencere olarak çağırmamız gerekir. Bunun faydasını ileride bir grup altında toplayabileceğimiz birden fazla kontrolümüz olduğunda (mesela YazGelistir.Animasyon, YazGelistir.Oylama vs.) görebiliriz.

 

Yukarıdaki kod parçacığına baktığımız zaman, YeniPencere kontrolümüzün HyperLink kontrolünden türettiğimizi (inheritence) görürüz. Yeni kontrolümüzün bir ASP.NET HyperLink kontrolü gibi davranmasını ama bazı ek özelliklerinin de olmasını istiyoruz. HyperLink kontrolünden türettiğimiz için yeni kontrolümüz hem HyperLink kontrolünün tüm özelliklerini taşıyacak, hem de eklediğimiz özelliklerle daha gelişmiş bir kontrol olacak. Aynı şekilde

 

public class YeniPencere: Button

 

şeklinde bir class tanımlaması, kontrolümüzü Button kontrolünden türetmemizi ve tüm özelliklerini kullanabilmemizi sağlardı. DataGrid gibi gelişmiş kontroller dahil ASP.NET’de yer alan tüm kontrollerin bu yolla gelişmiş ya da ihtiyaçlarınız için özelleştirilmiş versiyonlarını yaratabilirsiniz.

 

Kontrolümüz Gelişiyor

 

Nesneye yönelik programlamada class’lar, nesnelerin yapılarının ve becerilerinin tanımlamalarıdır. Bu tanımlara uygun bir nesne (object) yaratıldığında (instantiation), .NET Framework eğer varsa class tanımlamalarında yer alan constructor kodunu çalıştırır. Burada, nesnemiz hayatına başlarken gerek duyacağı ön ayarlamalar yapılır da diyebiliriz.

 

Daha önce boş olarak tanımladığımız constructor’ın içini şu şekilde dolduralım:

 

public YeniPencere(): base()

{

     Random ran = new Random(this.GetHashCode());

     WindowName = "BrowserWindow_"+ ran.Next().ToString();

                

     base.Target = "_blank";

}

 

Burada constructor’ımızın, inherit ettiğimiz HyperLink kontrolü yerine geçtiğini görüyoruz.

 

İlk kısımda, web sayfasında kullanacağımız kod için gerekli olan ve bu kontrolün her ‘instantiate’ edilişinde farklı olacak şekilde bir pencere adı oluşturduk.

 

İkinci kısım biraz daha önemli. Constructor tanımında da olduğu gibi burada da karşımıza base anahtar kelimesi (keyword) çıkıyor (Visual Basic için eşdeğeri: MyBase). Bu keyword’ü kullanarak inherit ettiğimiz kontrolün özelliklerine ulaşabilir ve metodlarını çağırabiliriz. Yukarıdaki kod parçacığında kontrolümüze temel olarak kullandığımız HyperLink kontrolünün Target adlı özelliğini _blank olarak belirttik.

 

Constructor’ımızda PencereAdi’na bir atama yapmış ama tanımlamasını yapmamıştık. Bu, bir özellik/nitelik (property) olarak şöyle tanımlanabilir:

 

public String PencereAdi

{

     get

     {

           object savedState;

             

           savedState = this.ViewState["PencereAdi"];

           if (savedState != null)

           {

                 return (String) savedState;

           }

           return "";

     }

     set

     {

           ViewState["PencereAdi"] = value;

     }

}

 

Bir public property olarak PencereAdi, dışarıdan bu değere bir atama yapılmasını ve gerektiğinde atanmış değerin öğrenilmesini sağlar.

 

Bu kod parçasında da dikkat etmemiz gereken bir şey var, ViewState kullanımı. Bir ASP.NET sayfasında kullanılabilecek tüm kontrollerin atası Control class’ıdır ve HyperLink kontrolü de buna dahildir. Yani bizim kontrolümüzün soy ağacını tam olarak şöyle gösterebiliriz:

 

-System.Object

-System.Control

          -System.Web.UI.WebControls.WebControl

                   -System.Web.UI.WebControls.HyperLink

                             -YazGelistir.YeniPencere

 

System.Control class’ının kendinden türetilecek kontrollere sunduğu özelliklerden biri ViewState’tir. ASP.NET sayfalarında ViewState, sayfa sunulurken (render) üzerindeki kontrollerin özelliklerini saklamak için kullanılır. Kullanıcı sayfayı geri postaladığı zaman (postback) ViewState’de saklanan değerler tekrar özelliklere atanır.

 

PencereAdi gibi, kontrolümüzün kulanıcıya sunması için gerekli diğer iki özellik olan genişlik ve yükseklik kodu da benzerdir (değişken tipi olarak, web sayfasına pixel değerler gönderileceği için unit kullanılmıştır); ekte verilen program kodunda detaylarını bulabilirsiniz.

 

En son ve en önemli konu, kontrolümüzün gerekli HTML kodunu ASP.NET tarafından oluşturulan web sayfasına nasıl yazacağıdır.

 

protected override void AddAttributesToRender(HtmlTextWriter writer)

{

     base.AddAttributesToRender(writer);

 

     StringBuilder ozellik = new StringBuilder();

 

     // Burada "ozellik" değişkeni içine web sayfasına gönderilecek

     // kod doldurulur. Örnek için ekte verilen program

     // koduna bakabilirsiniz.

 

     writer.AddAttribute("onclick", ozellik.ToString(), true);

}

 

AddAttributesToRender, yine Control class’ında tanımlanmış ve bizim kalıtım yoluyla edindiğimiz bir metotdur. Biz, kendi kodumuzda bu metodun değiştirerek (override) kendi kontrolümüğze uygun özellikler katıyoruz.

 

Bu metotda bize kullanmamız için bir HtmlTextWriter nesnesi verilir. Bu, sayfa yaratılırken oluşturulan ve sıra bizim kontrolümüze geldiğinde bizden kontrolümüze özel HTML kodunu eklememiz istenen, sayfadaki tüm kontrollerin kullandığı bir nesnedir.

 

AddAttributesToRender metodunu override ettiğimizden dolayı, base class’ımız olan HyperLink kontrolünün de sayfaya yazacağı HTML kodu olacağını düşünerek burada base.AddAttributesToRender metodunu çağırmayı unutmamalıyız. Daha sonra HtmlTextWriter.AddAttribute metodunu kullanarak linkimize onclick parametresini ekliyoruz.

 

Son olarak, Solution Explorer’da YeniPencere projemize sağ klikleyip Properties’i seçelim.

 

Build / Buid Solution yaparak projemizin hatasız olarak derlendiğinden emin olduğumuzda, kontrolümüzü başarıyla ürettik demektir.

 

Acaba çalışıyor mu?

 

Yazdığımız kontrolü test etmek için solution’ımıza File / Add Project / New Project... yaparak YeniPencereTest isimli yeni bir ASP.NET Web Application projesi ekleyelim (eklediğimiz projenin VB ya da C# projesi olması farketmez). Solution Explorer’da YeniPencereTest üzerine sağ klikleyerek Set as StartUp Project (başlangıç projesi) olarak işaretleyelim. Yine aynı projede References’a sağ klikleyerek Add Reference yapıp, açılan pencerenin Projects tab’ından YeniPencere projemizi seçelim (Şekil 3).

 

Kontrolümüzü YeniPencereTest projesindeki WebForm1.aspx sayfasında test edeceğiz. Öncelikle Solution Explorer’da sayfanın üzerine sağ klikleyip Set as Start Page’i seçelim. Şimdi sayfayı Visual Studio’da açıp şu hale getirelim.

 

<%@ Register TagPrefix="yg" Namespace="YazGelistir" Assembly="YazGelistir.YeniPencere"%>

<html>

  <head>

    <title>WebForm1</title>

  </head>

  <body>

    <formid="Form1"method="post"runat="server">

 

<yg:YeniPencereid="YeniPencere1"runat="server"Text="Test"

NavigateUrl="http://www.yazgelistir.com"Yukseklik="300px"

Genislik="300px"/>

 

    </form>

  </body>

</html>

 

Metin Kutusu:  
(Şekil 3)

F5’e basarak çalıştıralım. Açılan sayfadaki link’e tıkladığınızda, 300x300 boyutlarında yeni bir pencerede yazgelistir.com açılacaktır.

 

Eksikler ve Notlar

 

Kontrolümüz çalışır durumda olmasına rağmen şu haiyler Visual Studio içinden Toolbox’a eklenemez ve Properties penceresini kullanamaz. Bu özelliği kontrolümüze nasıl ekleyeceğimizi bir başka yazıda anlatacağız.

 

ASP.NET kontrolleri Visual Studio .Net olmaksızın, komut satırı kullanılarak da oluşturulabilir. Bunun için herhangi bir editorde yazacağınız kodu bir komut satırı derleyicisiyle derlemeniz gerekir. Örnek olarak, C# için:

 

csc.exe /target:library /out:Yazgelistir.YeniPencere.dll *.cs

 

İnternet üzerinde bu tip kontrolleri bulabileceğiniz en iyi kaynak doğal olarak www.asp.net sitesidir. Buradaki control gallery bölümünde ücretli ve ücretsiz kullanabileceğiniz bir çok kontrolü kaynak koduyla beraber bulabilirsiniz. Ayrıca, burada yarattığımız kontrolün biraz daha gelişmiş bir versiyonuna (BrowserWindow), başka kod örnekleriyle beraber altinoren.com’dan ulaşabilirsiniz. Bilgisayarınızda Visual Studio Combined Help yüklüyse, buraya tıklayarak Microsoft’un bu konuyla ilgili detaylı dökümantasyonunu gözden geçirmenizi şiddetle tavsiye ederim.

 

not: bu makaledeki örnek kodlar için lütfen tıklayın