Makale Özeti

Bu yazımızda ASP.NET AJAX ile resim albümlerimizi görüntüleyebileceğimiz bir resim slaytı hazırlayacağız. Bu örneği hazırlarken AJAX Extension kontrollerinden UpdatePanel ve Timer kontrollerinin bir web sayfasında diğer ASP.NET kontrolleri ile etkileşimli şekilde nasıl kullanılabileceğini de detaylı şekilde inceleme fırsatı bulacağız.

Makale

ASP.NET AJAX web uygulamalarına hızlı şekilde AJAX'ı uygulamamızı sağlayan bir kod kütüphanesidir. Beraberinde getirdiği kontroller ve yapılar aracılığıyla çok az kod yazarak çok hızlı AJAX uygulamaları geliştirebilmemizi sağlar. Bu makalemizde aslında bunun güzel bir örneğini görüyor olacağız. ScriptManager, UpdatePanel ve Timer kontrollerini kullanarak kullanıcının farklı albümlerdeki resimleri izleyebileceği, belirli resimlerde slayt gösterisini durdurabileceği, albüm içerisinde ileri-geri gidebileceği ve resimler arasındaki geçişleri hızlandırabileceği veya yavaşlatabileceği bir uygulama hazırlıyor olacağız. Burada anlatılan işlemler asenkron şekilde gerçekleşeceği için klasik uygulama modelinde hazırlanacak bir uygulamaya göre çok daha hızlı gerçekleşecektir.

Uygulamayı adım adım yapmaya başlamadan önce hazırlayacağımız sayfanın nasıl olacağını belirlemekte fayda var. Web sitemizde albumler ismindeki bir klasör altında alt klasörler ve bu klasörlerin içerisinde de resimlerimiz bulunuyor. Bu resim albümlerinin adlarını sayfamıza ekleyeceğimiz bir ListBox kontrolüne dolduracağız. Ardından kullanıcının bu listeden seçtiği resim albümünde bulunan resimler sayfada bulunan bir Image kontrolü ile slayt gösterisi olarak izlenebilecek. Resimlerin değiştirilmesi işlemi asenkron olarak gerçekleşeceği için Image kontrolünün bir UpdatePanel içerisinde yer alması gerekir. Timer kontrolüyle ise resimlerin belirli zaman aralıklarında değişmesi sağlanacaktır. Kullanıcı istediği zaman gösteriyi durdurup tekrar başlatabilecek ve albüm içerisindeki resimlerde ileri-geri giderek bir sonraki resime veya bir önceki resime geçişler yapabilecek. Önceki resime geçiş, sonraki resime geçiş, slaytı durdurma ve slaytı başlatma işlemleri için UpdatePanel'i tetikleyecek Button veya ImageButton gibi kontroller kullanılabilir. Yine resimler arasında hızlı veya yavaş geçiş yapabilmek için RadioButton kontrolleri kullanılarak seçim işlemi yaptırılabilir. Sanırım hazırlayacağımız sayfa ve kullanacağımız kontroller ile ilgili genel bir fikir sahibi olmuşuzdur. Adım adım ilerleyerek sayfamızı önce tasarlayıp ardından da arka planda çalışacak kodlarımızı yazalım.

Öncelikli olarak yeni bir Web Site projesi oluşturuyoruz. Visual Studio 2008'de ASP.NET 3.5 şablonu açarak veya Visual Studio 2005'te ASP.NET AJAX Enabled Web Site seçeneğini seçerek projemizi oluşturuyoruz. Yukarıda bahsettiğimiz kontrolleri sayfamızdaki bir tabloya düzgün şekilde yerleştiriyoruz. Image kontrolü asenkron olarak güncelleneceği için Image ve Timer'ı UpdatePanel içerisinde bulundurmamız gerekecektir. ImageButton ile RadioButton kontrolleri üzerinde tıklama ve seçim işlemleri gerçekleştiğinde asenkron güncellemeler yapılacağı için bu kontrollerin ilgili olaylarını UpdatePanel'in Triggers koleksiyonuna kayıt ediyoruz. ListBox kontrolünde yapılacak seçim işlemleri de UpdatePanel'in güncellenmesini gerektireceği için bu kontrolü de Triggers koleksiyonuna ekliyoruz. Timer kontrolü UpdatePanel'in içerisine eklendiği için trigger olarak eklememize gerek yoktur. Aşağıda sayfamızı oluşturan kodlar görülmektedir.

Default.aspx

<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<table width="100%">
   <tr>
      <td colspan="2" align="left">Seminerler Albümüm</td>
   </tr>
   <tr>
      <td width="15%" valign="top">
      <asp:ListBox ID="listAlbumler" runat="server" AutoPostBack="True" Rows="6"></asp:ListBox>
      </td>
      <td width="85%" valign="top">
         <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
               <asp:Image id="imgResim" runat="server" Width="400px" Height="300px"></asp:Image>
               <asp:Timer id="Timer1" runat="server" OnTick="Timer1_Tick" Interval="5000"></asp:Timer>
            </ContentTemplate>
            <Triggers>
               <asp:AsyncPostBackTrigger ControlID="listAlbumler"></asp:AsyncPostBackTrigger>
               <asp:AsyncPostBackTrigger ControlID="rbListHiz"></asp:AsyncPostBackTrigger>
               <asp:AsyncPostBackTrigger ControlID="btnOnceki"></asp:AsyncPostBackTrigger>
               <asp:AsyncPostBackTrigger ControlID="btnSonraki"></asp:AsyncPostBackTrigger>
               <asp:AsyncPostBackTrigger ControlID="btnDurdur"></asp:AsyncPostBackTrigger>
               <asp:AsyncPostBackTrigger ControlID="btnBaslat"></asp:AsyncPostBackTrigger>
            </Triggers>
         </asp:UpdatePanel>
         <asp:ImageButton ID="btnOnceki" runat="server" ImageUrl="~/images/geri.gif" />
         <asp:ImageButton ID="btnSonraki" runat="server" ImageUrl="~/images/ileri.gif" />
         <asp:ImageButton ID="btnDurdur" runat="server" ImageUrl="~/images/durdur.gif" />
         <asp:ImageButton ID="btnBaslat" runat="server" ImageUrl="~/images/baslat.gif" />
         <br /><b>Geçiş Hızı:</b>
         <br />
         <asp:RadioButtonList ID="rbListHiz" runat="server" AutoPostBack="true">
            <asp:ListItem Value="0">Yavaş</asp:ListItem>
            <asp:ListItem Value="1">Normal</asp:ListItem>
            <asp:ListItem Value="2">Hızlı</asp:ListItem>
         </asp:RadioButtonList>
      </td>
   </tr>
</table>
</form>

Sayfa ilk yüklendiğinde albumler klasöründe yer alan alt klasörler ListBox kontrolüne eklenecektir. Bu işlem için sayfamızın yüklenmesi esnasında System.IO isim alanı altında yer alan DirectoryInfo sınıfını (class) kullanıyor ve elde edilen dizinin elemanlarını listAlbumler kontrolünün Items koleksiyonuna ekliyoruz. ListBox ve RadioButton kontrollerindeki seçimlerin sayfada PostBack'ler gerçekleştirmesi için bu kontrollerin AutoPostBack özellikleri “True” olarak sayfamızın HTML kısmında ayarlanmıştı. Timer kontrolü ise Interval özelliği 5000 değerini taşıdığı için her 5 saniyede bir Timer1_Tick isimli metodun çalıştırılmasını sağlayacaktır. Bu noktada ise albüm içerisindeki resimlerin birer birer görüntülenebilmesi için gerekli işlemleri bu metot içerisinde gerçekleştirmemiz gerekecektir. Uygulamamızın ilerleyen kısımlarında resim gösterimi işlemlerini farklı yerlerden de çağırmamız gerekeceği için bu işlemi ResimGoster adındaki bir metoda yüklüyoruz. Bu metot string tipinde alacağı yon parametresi ile albümdeki resimlerin ileri veya geri yönde görüntülenmesini sağlayacaktır. Timer1_Tick metodu içerisinden slaytın varsayılan yönü olan "ileri" değeri ile ResimGonder metodu çağırılmaktadır. Aşağıda bu işlemler için sayfamızın code-behind kısmında oluşturacağımız kodlar yer almaktadır.

Default.aspx.cs

public partial class _Default : System.Web.UI.Page
{
   string dizin;

   protected void Page_Load(object sender, EventArgs e)
   {
      // Resim albümlerinin bulunduğu dizin
      dizin = Server.MapPath("albumler") + "\\";
      if (!Page.IsPostBack)
      {
         DirectoryInfo di = new DirectoryInfo(dizin);
         DirectoryInfo[] klasorler = di.GetDirectories();
         foreach (DirectoryInfo album in klasorler)
         {
            listAlbumler.Items.Add(album.Name);
         }
         listAlbumler.SelectedIndex = 0;
         ResimGoster("ileri");
      }
   }

   protected void Timer1_Tick(object sender, EventArgs e)
   {
      ResimGoster("ileri");
   }

   protected void ResimGoster(string yon)
   {
      // Seçili olan albümdeki resimlerin listesini alıp bir diziye atıyoruz 
      DirectoryInfo di = new DirectoryInfo(dizin + "\\" + listAlbumler.SelectedItem.Text); 
      FileInfo[] resimler = di.GetFiles("*.jpg"); 
      // Her postback işleminden sonra dizi içinde bir sonraki resime gideceğimiz için resim numarasını 
      // ViewState'de saklıyoruz ve her işlemde resim numarasını değiştiriyoruz 
      int resimNo; 
      if (ViewState["resimNo"] != null) 
      { 
         resimNo = (int)ViewState["resimNo"]; 
         // Eğer resimler ileri yönde izlenecekse 
         if (yon == "ileri"
         { 
            resimNo++; 
            // Eğer dizideki son resime gelinirse baştaki resime dönüyoruz 
            if (resimNo >= resimler.Length) 
               resimNo = 0; 
         } 
         // Eğer resimler geri yönde izlenecekse 
         else 
         { 
            resimNo--; 
            // İlk resime gelinmişse dizideki son resime dönüyoruz 
            if (resimNo < 0) 
               resimNo = resimler.Length - 1; 
         } 
         ViewState["resimNo"] = resimNo; 
      } 
      else 
      { 
         resimNo = 0; 
         ViewState["resimNo"] = resimNo;
 
      } 
      // Son olarak resmi imgResim adındaki kontrolde görüntülüyoruz 
      imgResim.ImageUrl = "albumler\\" + listAlbumler.SelectedItem.Text + "\\" + resimler[resimNo];
   }
}

Not: Hazırladığımız bu örnek disk üzerinde belirli bir klasörün içerisindeki alt klasörlerde yer alan .jpg uzantılı resimleri süzerek çalışacaktır. albumler klasöründe yer alan albümler ListBox kontrolüne aşağıda görüldüğü gibi aktarılacaktır. Diskte bulunan resimlerin bilgileri veritabanında tutalarak izlenen resimlerle ilgili detaylı bilgiler ve istatistkler de saklanabilir.


Şekil: albumler klasöründe yer alan albüm dizinleri ListBox'a yüklendi

ResimGoster() metodu resimlerin sıra ile görüntülenmesi işlemini gerçekleştirmektedir. Bu metodun yazımından sonra artık gerekli yerlerden metot çağırımının uygun şekilde yapılması yeterli olacaktır. Sayfa ilk yüklendiğinde Page_Load() metodu içerisinden yapılan ilk çağırım ListBox'ta seçili olarak gelen albümün ilk resmini gösterecektir. Timer kontrolü sayfa yüklendiğinde aktif olacağı için artık 5 saniyede bir Tick olayı (event) tetiklenecek ve olaya bağlanan metot aracılığıyla 5 saniyede bir resimler değişerek görüntülenecektir. Gerekli dizin ayarlamaları yapılıp örnek birkaç resim ile sayfanın düzgün şekilde çalıştığı test edilebilir. ListBox'tan farklı bir albümün seçilmesi durumunda slayt seçilen albüme geçerek albümde yer alan resimlerin görüntülemeye başlayacaktır. ResimGoster metodu dikkatle incelenirse her çalışmasında DirectoryInfo nesnesi o an listeden seçili olan albüm klasörüne göre oluşmaktadır. Böylece ListBox'ın SelectedIndexChanged olayı ile ilgili ek işlem yapmamıza gerek kalmamıştır.

Sayfaya eklenen butonlar aracılığıyla albümde kullanıcının ileri-geri gitmesi işlemleri ResimGoster() metodu üzerinden gerçekleştirilirken, slaytın durdurulması ve yeniden başlatılması ise Timer kontrolü ile sağlanacaktır. Geri butonuna tıklandığında ResimGoster() metodu "geri" değeri, İleri butonuna tıklandığında ise "ileri" değeri ile çağrılcaktır. Timer kontrolüne ait Enabled özelliği Timer kontrolünün aktif olma durumunu belirler. bool tipinden değer alan bu özelliğin varsayılan değeri true'dur ve bu değer Timer'ın çalışmasını sağlar. Böylece sayfanın belirli zaman aralıkları ile asenkron olarak güncellenmesi sağlanabilir. false değeri alması durumunda ise Timer aktif olmaz ve sayfada Timer kontrolü ile güncelleme yapılmaz. Durdur butonuna tıklandığında bu özellik false yapılırsa slayt duracak, Başlat butonuna tıklandığında ise özellik true yapıldığında slayt tekrar başlayacaktır. Bu butonların Click olayları UpdatePanel'in Triggers koleksiyonuna eklendiği için her tıklamada asenkron işlemler gerçekleşir yukarıda bahsedilen işlemler sayfa tamamen yenilenmeden gerçekleşir. Aşağıda bu dört ImageButton kontrolüne bağlanan metotlara yazılan kodlar görülmektedir.

Default.aspx

...
   <asp:ImageButton ID="btnOnceki" runat="server" ImageUrl="~/images/geri.gif" OnClick="btnOnceki_Click" />
   <asp:ImageButton ID="btnSonraki" runat="server" ImageUrl="~/images/ileri.gif" OnClick="btnSonraki_Click" />
   <asp:ImageButton ID="btnDurdur" runat="server" ImageUrl="~/images/durdur.gif" OnClick="btnDurdur_Click" />
   <asp:ImageButton ID="btnBaslat" runat="server" ImageUrl="~/images/baslat.gif" OnClick="btnBaslat_Click" />
...

Default.aspx.cs

protected void btnOnceki_Click(object sender, ImageClickEventArgs e)
{
   ResimGoster("geri"); // Bir önceki resme gidilir
}

protected void btnSonraki_Click(object sender, ImageClickEventArgs e)
{
   ResimGoster("ileri"); // Bir sonraki resme gidilir
}

protected void btnDurdur_Click(object sender, ImageClickEventArgs e)
{
   Timer1.Enabled = false; // Slayt durdurulur
}

protected void btnBaslat_Click(object sender, ImageClickEventArgs e)
{
   Timer1.Enabled = true; // Slayt yeniden başlatılır
}

Buraya kadar gerçekleştirdiğimiz işlemler sonucunda albümler arasında gezebileceğimiz, resimler üzerinde navigasyon işlemlerini gerçekleştirebileceğimiz bir slayt gösterisi hazırlamış olduk. Sıra projemizin son parçası olan slayt hızının ayarlanmasına geldi. Sayfamıza daha önceden eklediğimiz RadioButtonList kontrolüne Yavaş, Normal ve Hızlı olmak üzere üç seçenek eklenmişti. Kullanıcının bu kontrolden yapacağı seçime göre Timer kontrolünün Interval özelliğini değiştirerek slaytımızın hızının ayarlanmasını sağlayabiliriz. rbListHiz kontrolünün SelectedIndexChanged olayına bağlayacağımız metoda yazacağımız kodlar aşağıda görülmektedir.

Default.aspx

...
<asp:RadioButtonList ID="rbListHiz" runat="server" AutoPostBack="true" OnSelectedIndexChanged="rbListHiz_SelectedIndexChanged">
...

Default.aspx.cs

protected void rbListHiz_SelectedIndexChanged(object sender, EventArgs e)
{
   if (rbListHiz.SelectedIndex == 0)  // Çalışma şekli: Yavaş 
      Timer1.Interval = 8000;
   else if (rbListHiz.SelectedIndex == 1)  // Çalışma şekli: Normal
      Timer1.Interval = 5000;
   else if (rbListHiz.SelectedIndex == 2)  // Çalışma şekli: Hızlı
      Timer1.Interval = 2000;
}

Bu şekilde resimlerin kullanıcının istediği hızda görüntülenmesi de sağlanabilmektedir. Görüldüğü gibi resim slaytının bu şekilde kullanışlı hale gelmesinde Control Toolkit kontrollerinden Timer'ın etkisi oldukça büyüktür. Sayfamızı çalıştırıp test edecek olursak tüm parçaların sağlıklı şekilde çalıştığı görülecektir. Aşağıda sayfamızın çıktısı görülmektedir.


Resim: Resim slaytımızın son hali

Bu makalemizde ASP.NET AJAX kontrollerinden UpdatePanel ve Timer'ı kullandığımız örnek projede bir resim slaytı hazırladık. AJAX destekli çalışan resim albümüzde tüm güncellemeler asenkron şekilde gerçekleştiği için ziyaretçiler açısından oldukça hoş ve kullanışlı bir uygulama oluşturduğumuzu söyleyebiliriz. Bir başka makalede görüşmek dileğiyle.


Uğur UMUTLUOĞLU
www.umutluoglu.com
www.nedirtv.com