Makale Özeti

AJAX Control Toolkit içerisindeki Extender kontrollerini kullanmayanımız yoktur. Peki hiç kendi Extender kontrolünüzü yazmayı düşündünüz mü? Bu makalemizde örnek bir Extender kontrolü hazırlayarak ufkumuzu genişleteceğiz.

Makale

ASP.NET AJAX Extension kullandığımız web sitelerinde bize büyük kolaylık sağlayan AJAX Control Toolkit içerisindeki kontroller gibi Extender kontrolleri geliştirmek isterseniz tek yapmanız gereken makalemizi okumaya devam etmek. Peki bu gibi kontrolleri hazırlayabilmek için nelere ihtiyacımız olacak? Eğer web sitesi geliştirmek için Visual Web Developer Express kullanıyorsanız maalesef ek olarak Visual Basic 2005 Express Edition veya Visual C# 2005 Express Edition'ın da bilgisayarınızda yüklü olması gerekiyor. Kontrolümüzü geliştirme işini maalesef Visual Web Developer içerisinde yapamıyoruz. Eğer Visual Studio 2005 kullanıyorsanız herhangi bir sorun yaşamazsınız. Visual Studio içerisinde yaratmış olduğunuz herhangi bir web sitesini açarak File / Add / New Project menüsünden ASP.NET AJAX Control Project seçeneğini seçerek var olan Solution paketine extender kontrol projenizi ekleyebilirsiniz. Eğer Express sürümü geliştiricileri kullanıyorsanız kontrolü geliştirmek ve kullanmak için yukarıda bahsettiğim gibi farklı araçları kullanmanız gerekiyor. Ben makale boyunca Visual Studio 2005 kullanacağım.

AJAX Control Project yaratıyoruz...
Kendi AJAX Control projemizi yaratıyoruz.

Yaratacağımız örnek Extender kontrolünün adı SayacDugme olacak. Kontrolün amacı kendisine atanan bir metin kutusuna yazı yazıldıkça yazının uzunluğunu yine kendisine atanan bir düğmenin metnine eklemek. Genelde bu tarz uygulamalar web sitelerinde iletişim formlarında görülebiliyor. Aslına bakarsanız en uygun örnek cep telefonlarımızda yazdığımız SMSler. Telefonumuzda yazı yazdıkça kaç karakter yazdığımız bir köşede gösterilir. Bizim de oluşturacağımız Extender karakter sayısını alarak kendisine atanan bir düğmenin üzerine yazacak.

SayacDugme Extender projemizi Solution Explorer içerisinde görebiliyoruz.
SayacDugme Extender projemizi Solution Explorer içerisinde görebiliyoruz.

Extender kontrolümüz yaratıldığında oluşturulan dosyalar arasından ilk olarak SayacDugmeExtender.vb dosyası üzerinde çalışıyor olacağız. Dosya içerisinde hazır olarak gelen TargetControlType özelliğinin kontrol tipini aşağıdaki şekilde TextBox olarak değiştirmemiz gerekiyor. Her bir Extender kontrolünün otomatik olarak bir TargetControlID özelliği oluyor. Bizim Extender kontrolümüzde bu özelliğe atanacak kontrolün TextBox tipinde olması şart.

    <TargetControlType(GetType(TextBox))> _

Sıra geldi TargetControlID gibi ek bir parametre daha eklemeye. Extender kontrolümüzün bir metin kutusundaki harf sayısını kendisine atanan bir düğme üzerine yazacağından bahsetmiştik. Bu durumda söz konusu düğmeye ait ID bilgisinin de bir şekilde Extender'a iletilmiş olması gerekiyor.

        <ExtenderControlProperty()> _
        <DefaultValue("")> _       
        <IDReferenceProperty(GetType(Button))> _

        Public Property TargetButtonID() As String
            Get
                Return GetPropertyValue("TargetButtonID", "")
            End Get
            Set(ByVal value As String)
                SetPropertyValue("TargetButtonID", value)
            End Set
        End Property

Yukarıda da inceleyebileceğiniz üzere kontrolümüze ait ek özellikleri bir Property olarak tanımlıyoruz. Yapı az çok Class yapılarında kullandığımız Property'ler ile aynı. Örneğimizde Property adını TargetButtonID olarak düzenledik. Bu şekilde Property tanımlarken dikkat etmemiz gereken ufak birkaç nokta var. Eğer tanımlanan Property için gelecek değer başka bir kontrolün ID bilgisi ise üstteki IDReferenceProperty tanımlaması ile gelecek olan kontrolün tipini de belirleyebiliyoruz. Ayrıca her bir Property için ExtenderControlProperty özelliğinin de ayarlanması şart. İsterseniz Property ler için varsayılan değerleri de DefaultValue ile tanımlayabilirsiniz. Kodlar içerisinde kullandığımız GetPropertyValue ve SetPropertyValue metodları ise ileriki aşamalarda JavaScript tarafında tanımlayacağımız metodları kullanacak.

Kontrolümüze ek bir parametre daha ekliyor olacağız. Bu parametre sadece bir metin alacak. Extender kontrolümüz bir düğmenin üzerine toplam metin uzunluğunu yazarken ayrıca düğmenin adını da yazmalı. Örneğin "Gönder (56)" gibi bir yazının düğmenin üzerinde olması mantıklı olur. Bu durumda düğmenin üzerinde esas yazacak olan "Gönder" gibi bir metni de bizim kullanıcıdan alıyor olmamız gerekir.

        <ExtenderControlProperty()> _
        <DefaultValue("")> _
        Public Property Metin() As String
            Get
                Return GetPropertyValue("Metin", "")
            End Get
            Set(ByVal value As String)
                SetPropertyValue("Metin", value)
            End Set
        End Property

Bir önceki adımda olduğu gibi burada da bir Property tanımladık. Bu Property'nin tek farkı bir kontrolün ID bilgisini taşımayacağı için IDReferenceProperty özelliğine sahip olmaması. Sunucu tarafındaki kodumuzu tamamladık. SayacDugmeExtender.vb dosyamızın son hali aşağıdaki şekilde.

Imports System
Imports System.ComponentModel
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports AjaxControlToolkit
 
#Region "Assembly Resource Attribute"
<Assembly: System.Web.UI.WebResource("SayacDugme.SayacDugmeBehavior.js", "text/javascript")>
#End Region
 
Namespace SayacDugme
 
    <Designer(GetType(SayacDugmeDesigner))> _
    <ClientScriptResource("SayacDugme.SayacDugmeBehavior", "SayacDugme.SayacDugmeBehavior.js")> _
    <TargetControlType(GetType(TextBox))> _
    Public Class SayacDugmeExtender
        Inherits ExtenderControlBase
        
        <ExtenderControlProperty()> _
        <DefaultValue("")> _
        <IDReferenceProperty(GetType(Button))> _
        Public Property TargetButtonID() As String
            Get
                Return GetPropertyValue("TargetButtonID", "")
            End Get
            Set(ByVal value As String)
                SetPropertyValue("TargetButtonID", value)
            End Set
        End Property
 
        <ExtenderControlProperty()> _
        <DefaultValue("")> _
        Public Property Metin() As String
            Get
                Return GetPropertyValue("Metin", "")
            End Get
            Set(ByVal value As String)
                SetPropertyValue("Metin", value)
            End Set
        End Property
 
    End Class
 
End Namespace

Sıra geldi istemci tarafında çalışacak olan JavaScript kodlarımızı yazmaya. Tüm JavaScript kodlarımızı projemize ait SayacDugmeBehavior.js dosyası içerisine yazıyor olacağız. Sunucu tarafında tanımladığımız Property'ler ile ilgili fonksiyonları ve değişkenleri JavaScript tarafında da tanımlamamız gerekiyor. İlk olarak önümüze gelen JavaScript dosyasında aşağıdaki şekilde değişkenlerimizi tanımlayalım.

SayacDugme.SayacDugmeBehavior = function(element) {
    SayacDugme.SayacDugmeBehavior.initializeBase(this, [element]);
    this._TargetButtonIDValue = null;
    this._MetinValue = null;
};

Gördüğünüz gibi TargetButtonID ve Metin Property'leri için birer JavaScript değişkeni tanımladık ve başlangıç için değerlerini null olarak verdik. Bir sonraki adımda bu değişkenlerin get ve set metodlarını yazıyor olacağız.

    get_TargetButtonID : function() {
        return this._TargetButtonIDValue;
    },
    set_TargetButtonID : function(value) {
        this._TargetButtonIDValue = value;
    },
    get_Metin : function() {
        return this._MetinValue;
    },
    set_Metin : function(value) {
        this._MetinValue = value;
    }

Yukarıdaki tüm JavaScript fonksiyonlarını SayacDugmeBehavior'ın prototype'ına tanımlıyoruz. Sıra geldi metin kutusuna yazı yazıldıkça düğmenin üzerine gerekli metni yazacak JavaScript fonksiyonunu yazmaya.

         _onkeyup : function() {
               var harf_sayisi = this.get_element().value.length;
               var dugme = $get(this._TargetButtonIDValue);
               dugme.value = this._MetinValue + '(' + harf_sayisi + ')';
         },

Gördüğünüz gibi prototip tanımlamasına eklediğimiz bu fonksiyon ile ilk olarak harf sayisini bir değişkene alıyoruz. this.get_element() metodu bize extender kontrolümüzün TargetControlID'sine verilmiş kontrolünü getirecek. Extender kontrolüne bağlanan düğmeyi de JavaScript ile yakalayabilmek için kontrolümüze aktarılan ID bilgisi üzerinden yola çıkarak $get metodunu kullanıyoruz. Son olarak düğmenin üzerine yazılacak yazıyı oluştururken de extender kontrolümüze verilmiş Metin yazısı ile toplam harf sayısını uygun şekilde birleştiriyoruz.

Fonksiyonumuzu tamamladık, fakat hala bize verilen metin kutusunun keyup özelliğine bağlanmadı. Sayfa ilk yüklendiğinde extender kontrolüne ait initialize metodu çalıştırılır. Bizim de söz konusu anda gerekli durum bağlantılarını yapmamız gerekiyor.

    initialize : function() {
        SayacDugme.SayacDugmeBehavior.callBaseMethod(this, 'initialize');
        $addHandler(this.get_element(), 'keyup',
        Function.createDelegate(this, this._onkeyup));
             this._onkeyup();
    },

ASP.NET AJAX istemci kütüphanesinden $addHandler metodunu kullanarak extender kontrolümüze atanmış metin kutusunun keyup durumuna elimizdeki fonksiyonu bağlıyoruz. Son satırda da söz konusu fonksiyonu bir defalığına çalıştırıyoruz, böylece sayfa ilk yüklendiğinde düğme üzerinde sayaç sıfırı gösteriyor olacak. Kodumuz sonlandığına göre tüm JavaScript dosyamızın yapısını aşağıda inceleyebilirsiniz.

Type.registerNamespace('SayacDugme');
 
SayacDugme.SayacDugmeBehavior = function(element) {
    SayacDugme.SayacDugmeBehavior.initializeBase(this, [element]);
    this._TargetButtonIDValue = null;
    this._MetinValue = null;
};
 
SayacDugme.SayacDugmeBehavior.prototype = {
         _onkeyup : function() {
               var harf_sayisi = this.get_element().value.length;
               var dugme = $get(this._TargetButtonIDValue);
               dugme.value = this._MetinValue + '(' + harf_sayisi + ')';
         },
    initialize : function() {
        SayacDugme.SayacDugmeBehavior.callBaseMethod(this, 'initialize');
        $addHandler(this.get_element(), 'keyup',
        Function.createDelegate(this, this._onkeyup));
             this._onkeyup();
    },
    dispose : function() {
        SayacDugme.SayacDugmeBehavior.callBaseMethod(this, 'dispose');
    },
 
    get_TargetButtonID : function() {
        return this._TargetButtonIDValue;
    },
    set_TargetButtonID : function(value) {
        this._TargetButtonIDValue = value;
    },
    get_Metin : function() {
        return this._MetinValue;
    },
    set_Metin : function(value) {
        this._MetinValue = value;
    }
};
 
SayacDugme.SayacDugmeBehavior.registerClass('SayacDugme.SayacDugmeBehavior', AjaxControlToolkit.BehaviorBase);

Tüm bu işlemleri tamamladıktan sonra projenizi Build ederek oluşacak SayacDugme.dll dosyasını araç çubuğunuza ekleyebilir ve tüm projelerinizde hazırladığımız Extender kontrolünü kullanabilirsiniz. Fakat unutmamakta fayda var; Extender kontrolümüz bir AJAX Control Toolkit Extender'ı olduğu için eklendiği her projeye AJAX Control Toolkit'e ait DLL dosyasını da ekleyecektir. Bilgi olarak aklımızda olmasında fayda var. Kontrolümüzü kullandığımız bir web sayfasının HTML kodu aşağıdaki şekilde sonuçlanıyor.

SayacDugme Extender kontrolümüz iş başında.
SayacDugme Extender kontrolümüz iş başında.

<%@ Page Language="VB" AutoEventWireup="true" CodeFile="Default.aspx.vb" Inherits="_Default" %>

<%@ Register Assembly="SayacDugme" Namespace="SayacDugme.SayacDugme" TagPrefix="Daron" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
        <ajaxToolkit:ToolkitScriptManager ID="ScriptManager1" runat="server" />
        <div>
          <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox><asp:Button ID="Button1"
            runat="server" Text="Button" />
            <Daron:SayacDugmeExtender ID="SayacDugmeExtender1" runat="server"
                                      TargetControlID="TextBox1"
                                      TargetButtonID="Button1"
                                      Metin="TIKLA">
            </Daron:SayacDugmeExtender>
        </div>
     
    </form>
</body>
</html>

Hepinize kolay gelsin.

Daron Yöndem
MCPD, MCITP, MCTS, MCSD, MCAD
MCDBA, MCP, ACP, ICSD, IEL'03
http://daron.yondem.com