Makale Özeti

AJAX projelerinde çok büyük kolaylıklar sağlayan AJAX Control Toolkit sunucu kontrolleri arasından belki de dokümantasyonu en zayıf olan ve bu nedenle en az kullanılan kontrollerden birini; Animation Extender kontrolünü detaylıca incelediğimiz bu makaleyi okuduktan sonra XML kodu yazarak nasıl DHTML animasyonların kolayca oluşturulabileceğini keşfedeceksiniz.

Makale

ASP.NET AJAX1.0 sürümü gün geçtikçe projelerde daha sık kullanılır olmakla kalmayıp artık bir standart olarak kabul edilmeye başladı. Durum böyle olunca AJAX Control Toolkit içerisindeki birçok kontrol ile çok sayıda projede karşılaşıyoruz. Tüm Control Toolkit’de benim en çok ilgimi çeken kontrollerden biri olan Animation Extender maalesef dokümantasyon eksikliği yüzünden pek kullanılamıyor. Umarım bu makale ile bu boşluğu dolduruyor olacağız.

Konunun özüne dönersek, AJAX Control Toolkit Animation Extender kontrolü bize XML kodları yazarak DHTML animasyonları yaratma olanağı sağlıyor. Bu konsept bizim ileride Silverlight ile daha da aşina olacağımız XAML (XML kodu) ile animasyon yaratma konseptine çok yakın. Hızlı bir şekilde ilk örneğimize geçmeden önce bilgisayarınızda ASP.NET AJAX 1.0 ve AJAX Control Toolkit’in yüklü olduğundan emin olalım, eğer gerekli yüklemeler bilgisayarınızda eksikse aşağıdaki adreslerden indirerek hemen yükleyebilirsiniz.

http://www.microsoft.com/downloads/details.aspx?FamilyID=ca9d90fa-e8c9-42e3-aa19-08e2c027f5d6&displaylang=en
http://www.codeplex.com/AtlasControlToolkit/Release/ProjectReleases.aspx?ReleaseId=4923

Yükleme sonrası Visual Studio veya Visual Web Developer Express içerisinde ASP.NET web sitesi yaratmak istediğinizde seçenek olarak “AJAX Control Toolkit Web Site” seçeneği de karşınıza çıkacaktır. Hali hazırda var olan web sitelerinizde AJAX Control Toolkit kontrollerini kullanmak için download paketi içerisinde yer alan AjaxControlToolkit.dll adındaki DLL dosyasını projenize referans olarak eklemeniz yeterli. Eğer Toolbar'ınızda gerekli kontroller listelenmez ise Toolbar'a sağ tuş "Choose Items" diyerek yine DLL dosyasını göstererek kontrolleri ekleyebilirsiniz.

AJAX Control Toolkit Web Site yaratırken Visual Studio ekranı...

Yeni bir “Ajax Control Toolkit Web Site” yarattıktan sonra karşımıza ilk çıkan default.aspx dosyasına Toolbar içerisinden bir AnimationExtender eklediğimizde sayfamızın tasarım bölümünde aşağıdaki HTML kodu ile karşılaşıyoruz

<%@ Page Language="VB" AutoEventWireup="true" CodeFile="Default.aspx.vb" Inherits="_Default" %>
 
<!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>
            <ajaxToolkit:AnimationExtender ID="AnimationExtender1" runat="server">
            </ajaxToolkit:AnimationExtender>
        </div>
    </form>
</body>
</html>

Sayfa içerisinde toplam iki adet kontrol bulunuyor. Bunlardan ilki olan ToolkitScriptManager sayfamızı ilk açtığımızda zaten içerisinde vardı. ASP.NET AJAX 1.0 ile daha önce projeler gerçekleştirmiş olanlar hatırlayacaktır; AJAX özellikleri kullanacağımız her sayfada ScriptManager adında bir kontrolün sayfanın en başında yer alması gerekiyordu. ScriptManager sayfamızdaki diğer AJAX kontrollerinin çalışabilmesi ve bizim istemci taraflı AJAX kodları yazarken Microsoft kütüphanesinden faydalanabilmemiz için gerekli olan tüm JavaScript kütüphanelerinin sayfaya eklenmesini sağlıyor. AJAX Control Toolkit söz konusu olduğunda Control Toolkit içerisindeki her kontrolün kendi ayrı JavaScript dosyalarının da sayfaya eklenmesi gerektiğini düşünürsek bazen bir sayfada kullanılan farklı AJAX kontrolleri nedeniyle 10-15 adet farklı JavaScript dosyalarının arkaplanda sayfaya eklenmiş olduğunu görebiliyorduk. Aslında tüm bu JavaScript kodlarının olabildiğince daha az sayıda dosyada derlenmesi ve toplu olarak sayfaya eklenmesi daha mantıklı olacaktır. İşte bu bahsettiğimiz optimizasyonu bizim yerimize ToolkitScriptManager yapacak. Bunun için de klasik ASP.NET AJAX ScriptManager yerine Control Toolkit kullanılan projelerde artık ToolkitScriptManager kullanıyor olacağız.

Sayfadaki diğer kontrol bizim biraz önce eklediğimiz AnimationExtender kontrolü. Gelin şimdi hızlı bir şekilde bu kontrolün aldığı özelliklere bakmak için aşağıdaki kodu inceleyelim.

<ajaxToolkit:AnimationExtender ID="AnimationExtender1" runat="server" TargetControlID="Button1">
    <Animations>
        <OnLoad> ... </OnLoad>
        <OnClick> ... </OnClick>
        <OnMouseOver> ... </OnMouseOver>
        <OnMouseOut> ... </OnMouseOut>
        <OnHoverOver> ... </OnHoverOver>
        <OnHoverOut> ... </OnHoverOut>
    </Animations>
</ajaxToolkit:AnimationExtender>

AnimationExtender kontrolümüz kendi içerisinde tanımlayacağımız tüm animasyonlara sayfadaki hangi elementin neden olacağını TargetControlID aracılığı ile bizden öğreniyor. Örneğin sayfada bir düğmeye tıklanacak ve sonrasında animasyon uygulanacaksa TargetControlID değerine söz konusu düğmenin ID bilgisini vermemiz gerekiyor. Tabi sadece tıklama (OnClick) gibi durumlarla sınırlandırılmış değiliz; yukarıdaki kod içerisinde de görebileceğiniz gibi OnLoad, OnMouseOver gibi çok sayıda durum (event) söz konusu. Her bir durumda uygulanmak üzerine farklı animasyonlar tanımlayabiliyoruz, fakat tüm bu durumlar TargetControlID özelliğine aktarılmış elementin durumlarına bağlı olacak.
Animasyonlarımızı XML kodları ile yazacağımızdan bahsetmiştim. Her bir farklı durum (onclick, onload… vs) için farklı animasyanları hazırladıktan sonra yukarıdaki örnekteki uygun duruma ait (onclick vs) XML taglarının arasına yazmamız gerekiyor. Hemen bir örnek ile ilerleyelim.

<ajaxToolkit:AnimationExtender ID="AnimationExtender1" runat="server" TargetControlID="Button1">
    <Animations>
        <OnHoverOver>
          <FadeOut Duration=".5" Fps="20" MinimumOpacity=".1" />
        </OnHoverOver>
        <OnHoverOut>
          <FadeIn Duration=".5" Fps="20" MinimumOpacity=".1" />
        </OnHoverOut>
    </Animations>
</ajaxToolkit:AnimationExtender>
 <asp:Button ID="Button1" runat="server" Text="Button" />

Sayfamıza ayrıca bir Button ekledik. Bu düğmeyi hedef kontrol yani TargetControlID olarak ayarladık. AnimasyonExtender içerisinde FadeIn ve FadeOut olarak iki farklı animasyonu hedef kontrolün iki farklı durumuna (OnHoverOver ve OnHoverOut) tanımladık. Böylece fare ile hedef kontrolün üzerine gelindiğinde OnHoverOver içerisinde tanımlanmış animasyon, fare ile hedef kontrolün üzerinden ayrıldığımızda ise OnHoverOut içerisindeki animasyon çalışacak. Animasyonların tanımlanması ile ilgili detayları birazdan inceleyeceğiz, şimdilik durum kontrolüne konsantre olarak yukarıdaki kodu tekrar incelemenizi tavsiye ediyorum.
Animasyon tanımlamalarımızı yaparken iki farklı seçeneğimiz var. Bunlardan ilki Sequence animasyon, diğeri ise Parallel. Sequence animasyon tagları içerisinde yer alan tüm animasyonlar tek tek, XML kodu içerisine yazılma sıraları ile gerçekleştirilir. Bir animasyon bitmeden diğerine geçilemez. Parallel animasyonlarda ise tüm animasyon aynı anda çalışır. Bir Sequence animasyon içerisinde bir Parallel animasyon yer alabileceği gibi tam tersi de olabilir. Gelin yine örnek üzerinden gidelim.
Örneğimizdeki sayfaya bir ASP.NET Calendar kontrolü ekleyeceğim. Sayfada yer alacak olan iki farklı düğmeden biri Calender kontrolünü %10 şeffaf yapacak, diğeri ise tekrar görünür hale getirecek. İki farklı hedef kontrolüm, yani iki farklı TargetControl olacağı için mecburen iki farklı AnimationExtender kullanacağım.

<ajaxToolkit:AnimationExtender ID="AnimationExtender1" runat="server" TargetControlID="Button1">
    <Animations>
        <OnClick>
          <Sequence AnimationTarget="Calendar1">
            <FadeOut Duration=".5" Fps="20" MinimumOpacity=".1" />
          </Sequence>
        </OnClick>
    </Animations>
</ajaxToolkit:AnimationExtender>
  <ajaxToolkit:AnimationExtender ID="AnimationExtender2" runat="server" TargetControlID="Button2">
    <Animations>
        <OnClick>
          <Sequence AnimationTarget="Calendar1">
            <FadeIn Duration=".5" Fps="20" MinimumOpacity=".1" />
          </Sequence>
        </OnClick>
    </Animations>
</ajaxToolkit:AnimationExtender>
<asp:Button ID="Button1" runat="server" OnClientClick="return false" Text="Görünmez Yap" />
<asp:Button ID="Button2" runat="server" OnClientClick="return false" Text="Görünür Yap" />
<asp:Calendar ID="Calendar1" runat="server"></asp:Calendar>

Yukarıdaki kod içerisinde bizim için yeni olabilecek iki şey var. Bunlardan ilki Sequence animasyonlar ve bu animasyonlara ait AnimationTarget özellikleri. Daha önceki örneğimizde animasyona neden olan kontrol, yani TargetControl ile animasyonun gerçekleştiği kontrol aynıydı. Oysa şu an biz bir düğmeye tıklayıp başka bir kontrole animasyon uygulamak istiyoruz. Bu nedenle animasyon serisine yani Sequence animasyonuna bir hedef belirtmemiz gerekiyor. Örneğimizde bu kontrol Calendar1 olacak çünkü animasyonu takvime uygulayacağım. Bir ikinci ilginç nokta da düğmelerimize verdiğimiz OnClientClick özellikleri. Sayfada normal ASP.NET düğmeleri kullandığımız için doğal olarak düğmelere her tıkladığımızda sayfa PostBack oluyor. Oysa bizim animasyonların çalışabilmesi için bunu engellememiz şart. Bu nedenle ClientClick özelliklerine “return falseJavaScript kodunu yazıyoruz. Böylece söz konusu düğmelere tıklandığında sayfa PostBack olmayacak, sadece animasyonlar çalışacak.
Şimdi bir de Parallel animasyon denemesi yapalım. Parallel animasyon tagları arasında iki farklı animasyon koyacağız. Animasyonlardan biri yine takvimin görünürlük değerini değiştirirken diğeri de aynı takvimin fon rengini beyazdan kırmızıya ve kırmızıdan beyaza çevirecek.

<ajaxToolkit:AnimationExtender ID="AnimationExtender1" runat="server" TargetControlID="Button1">
    <Animations>
        <OnClick>
          <Parallel AnimationTarget="Calendar1">
            <FadeOut Duration=".5" Fps="20" MinimumOpacity=".1" />
            <Color PropertyKey="backgroundColor" StartValue="#FFFFFF" EndValue="#ff0000" />
          </Parallel>
        </OnClick>
    </Animations>
</ajaxToolkit:AnimationExtender>
  <ajaxToolkit:AnimationExtender ID="AnimationExtender2" runat="server" TargetControlID="Button2">
    <Animations>
        <OnClick>
          <Parallel AnimationTarget="Calendar1">
            <FadeIn Duration=".5" Fps="20" MinimumOpacity=".1" />
            <Color PropertyKey="backgroundColor" StartValue="#ff0000" EndValue="#FFFFFF" />
          </Parallel>
        </OnClick>
    </Animations>
</ajaxToolkit:AnimationExtender>
<asp:Button ID="Button1" runat="server" OnClientClick="return false" Text="Görünmez Yap" />
<asp:Button ID="Button2" runat="server" OnClientClick="return false" Text="Görünür Yap" />
<asp:Calendar ID="Calendar1" runat="server"></asp:Calendar>

Ekran Görüntüsü

Animasyonlar içerisinde kullanabileceğiniz farklı animasyon taglarını sırayla inceleyelim.

<Resize Width="200" Height="300" Unit="px" />

Yukarıdaki animasyon ile hedef elementin yüksekliğinin ve genişliğinin verilen değerlere doğru bir animasyon ile büyütülmesini veya küçültülmesini sağlayabilirsiniz.

<EnableAction Enabled="false" />

Özellikle düğmelerin tıklanabilir olması veya olmaması arasında geçiş yapmak için yukarıdaki animasyon kodunu kullanabilirsiniz. Bir düğmenin rengini açık bir renkten koyu bir renge çevirirken aynı anda paralel bir animasyonda düğmeyi tıklanamaz hale de getirebilirsiniz.

<ScriptAction Script="alert('Selamlar!');" />

Sadece animasyon yapmakla kalmayıp animasyonlarınızın belirli noktalarında JavaScript kodları da çalıştırabilirsiniz. Bu özellik animasyonlar tamamlandıktan sonra kullanılırsa animasyonun bitmesi ile sayfada farklı işlemler yapabilmenizi sağlayabilir.

<Color AnimationTarget="MyContent"
 Duration="1"
 StartValue="#FF0000"
 EndValue="#666666"
 Property="style"
 PropertyKey="backgroundColor" />

Objelerin CSS özellikleri üzerinde direk oynamak için yukarıdaki kodu kullanabilirsiniz. Örneğin bu kod içerisinde hedef objenin fon rengi değiştiriliyor.

<StyleAction Attribute="display" Value="none" />

CSS özelliklerinin değişimi ile ilgili alternatif olarak StyleAction animasyonunu da kullanabilirsiniz.
Peki ya sayfadaki bir duruma, bir koşula göre farklı animasyonların çalışmasını istiyorsanız? Merak etmeyin, bunun için de bir çözüm var.

<Condition ConditionScript="$get('isaret').checked">
    <FadeOut AnimationTarget="up_container" minimumOpacity=".2" />
</Condition>

Yukarıdaki gibi condition tagı ile direk sayfadaki bir CheckBox’ın işaretli olup olmadığını kontrol edebileceğiniz gibi herhangi bir JavaScript komutu da çalıştırabilir veya sayfada tanımlı global bir JavaScript değişkenini kontrol edebilirsiniz. Şart sağlandığında Condition tagları arasındaki animasyon uygulanacaktır, aksi halde pas geçilecektir.

<FadeOut Duration=".5" Fps="20" MinimumOpacity=".1" />

FadeIn ve FadeOut animasyonlarını daha önce de kullandık. Detaylı olarak incelemek gerekirse söz konusu animasyonlar için animasyon süresini Duration özelliğine aktarmamız gerekiyor. Diğer yandan isterseniz animasyonun saniyede kaç kare gösterimi ile oluşturulacağına da Fps değeri ile karar verebilirsiniz. Son olarak şeffaflığa gidiş veya şeffaflıktan dönüş animasyonlarında MinimumOpacity ve MaximumOpacity ile minimum şeffaflık ve maksimum şeffaflık limitlerini de ayarlayabilirsiniz.

Tüm bu animasyonları isterseniz direk JavaScript ile de oluşturabilir ve kullanabilirsiniz.

var effects = new Array();
effects[0] = new AjaxControlToolkit.Animation.FadeInAnimation($get("Calendar1"), .3, 30, .3, 1, false);
AjaxControlToolkit.Animation.SequenceAnimation.play($get("Calendar1"), 0, 24, effects, 1); 

Yukarıdaki JavaScript kodumuz içerisinde ilk olarak animasyonlarımızın bir listesini saklayacak Array tipindeki değişkenimizi tanımlıyoruz. Benim değişkenimde sadece tek bir animasyon var, siz isterseniz birden çok animasyon ekleyebilirsiniz. Animasyonlarla ilgili parametreleri yine JavaScript ile aktarıyoruz. Son olarak da AjaxControlToolkit’e ait JavaScript sınıfları aracılığı ile hazırladığımız animasyon serisini bir SequenceAnimation olarak oynatmak için .play komutunu kullanıyoruz. Her bir animasyon için hedef HTML elementini ve gerekli animasyon parametrelerini vermemiz gerekiyor. XML-Script’e kıyasla biraz daha zor bir teknik olduğu için benim tavsiyem AnimationExtender animasyonlarını JavaScript ile birazdan inceleyeceğimiz şekilde kullanmanızdır.

<div id="gereksiz" runat="server" style="display:none;"></div>
<ajaxToolkit:AnimationExtender ID="AnimationExtender1" BehaviorID="Yoket" runat="server" TargetControlID="gereksiz">
    <Animations>
        <OnClick>
          <Parallel AnimationTarget="Calendar1">
            <FadeOut Duration=".5" Fps="20" MinimumOpacity=".1" />
            <Resize Width="400" Unit="px" />
          </Parallel>
        </OnClick>
    </Animations>
</ajaxToolkit:AnimationExtender>
  <ajaxToolkit:AnimationExtender ID="AnimationExtender2" BehaviorID="Goster" runat="server"  TargetControlID="gereksiz">
    <Animations>
        <OnClick>
          <Parallel AnimationTarget="Calendar1">
            <FadeIn Duration=".5" Fps="20" MinimumOpacity=".1" />
            <Resize Width="200" Unit="px" />
          </Parallel>
        </OnClick>
    </Animations>
</ajaxToolkit:AnimationExtender>
<input id="Button4" type="button" value="Yoket" onclick="var onclkBehavior = $find('Yoket').get_OnClickBehavior().get_animation();onclkBehavior.play();" />
<input id="Button1" type="button" value="Goster" onclick="var onclkBehavior = $find('Goster').get_OnClickBehavior().get_animation();onclkBehavior.play();" />
<input id="Button2" type="button" value="Gostermeye Ara Ver" onclick="var onclkBehavior = $find('Goster').get_OnClickBehavior().get_animation();onclkBehavior.pause();" />
<asp:Calendar ID="Calendar1" runat="server"></asp:Calendar>

Yukarıdaki örneğimizde AnimationExtender kontrolleri içerisinde tanımladığımız animasyonları JavaScript ile çalıştırıyoruz. Normal şartlarda AnimationExtender’lar başka .NET kontrollerine bağlanmak zorunda oldukları için yalancı bir .NET kontrolü yaratıp AnimationExtender kontrollerinin TargetControlID özelliklerini boş geçmememiz gerekiyor. Bunun için kodun en başında bir DIV yaratarak CSS özelliği ile görünmez yaptım. Söz konusu DIV’i her iki AnimationExtender’a da TargetControlID olarak verdim. Böylece bir sorun yaşamayacağız. AnimationExtender kontrollerini JavaScript ile yakalayabilmek için her iki kontrole de farklı BehaviorID isimleri atadım. Kontrollerin BehaviorID özelliklerindeki isimlerden animasyonları yakalayacağız. Gelelim bizim esas animasyonları oynatacak olan JavaScript kodlarımızın bulunduğu düğmelere. Formun en altında toplam dört adet HTML düğmesi bulunuyor. Bu düğmelerin OnClick özelliklerine ikişer satırlık JavaScript kodları koydum. Bu kodları tek tek incelemekte fayda var.

var onclkBehavior = $find('Yoket').get_OnClickBehavior().get_animation();
onclkBehavior.play();

İlk satırda sayfadaki animasyonumu yakalayacak olan komut bulunuyor. get_OnClickBehavior(). Komutu ile söz konusu animasyona ait OnClick durumuna atanmış animasyonu alabiliyoruz. Aldığımız animasyonu onclkBehavior adındaki değişkene aktardıktan sonra .play() komutu ile oynatıyoruz.

var onclkBehavior = $find('Goster').get_OnClickBehavior().get_animation();
onclkBehavior.pause();

.pause() komutu söz konusu animasyonu durduruyor. Fakat sonrasında tekrar play() komutu ile bu animasyonu devam ettirmek mümkün.

Umarım hepiniz için bu ilk yazgelistir.com makalem faydalı bir kaynak olmuştur. Silverlight ile web dünyasına giriş yapmadan önce bir süre için DHTML animasyon ihtiyaçlarınızı AnimationExtender kontrolü ile sağlayabileceğinizden eminim.

Herkese kolay gelsin…

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