Makale etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Makale etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

Çarşamba, Temmuz 08, 2009

Asp.Net MVC Framework - Master Pages Kavramı - I

Microsoft 'un web projelerini hazırlarken bizlere mimari tasarıları daha basit ve kullanışlı bir biçimde kullanmamızı sağlayan Asp.Net MVC Framework 'ü daha önceki yazılarımızda detaylı bir biçimde tanımaya çalıştık. Peki neler yapabiliyorduk. Son kullanıcıdan gelen istekler doğrultusunda başka bir sayfaya nasıl yönlendirebileceğimizi, Controller katmanı ile veri tabanı işlemlerini nasıl işleyip görsel sayfaya ileteceğimizi, model katmanı yardımı ile veri tabanı ile haberleşmelerin çok daha basit bir şekilde yapılabileceğini, veri tabanını aktif olarak kullandığımızda nasıl bir uygulama geliştirdiğimizi ve view sayfaları nasıl kolayca oluşturabileceğimizi detaylı olarak daha önceki yazılarımızda inceledik ve neler yapabileceğimizi gördük. Ayrıca uygulamalarımızda MVC tasarımını kullandığımızda daha önceden oldukça fazla uğraştığımız işlemleri ne kadar kolaylıkla yapabildiğimizi defalarca yapmış olduğumuz pratiklerde doğrulamış olduk. Bu yazımızda ise Asp.Net sayfalarında tasarım standardı açısından sıkça kullandığımız Master Pages kavramını MVC Framework 'te kullanım yapısını detaylı olarak inceliyor olacağız.

Asp.Net uygulamaların Master Page kullanmamızın sebebini kısaca hatırlayacak olursak. Benzer tarzda tasarım şablonu kullanacak olduğumuz sayfalarda tekrardan o tasarımsal öğeleri serverdan çağırıp sayfa üzerinde yüklenmemesini beklememek için oluşturulmuş başarılı bir yapıdır. Özellikle tasarım yapısı üzerinde herhangi bir değişiklik yok ise ve sadece içerikler değişecekse çok önemli bir tercih durumundadır. Aynı Asp.Net uygulamalarında olduğu gibi MVC uygulamalarında da Master Page kavramı önemli bir yer tutmaktadır. Varsayılan olan mavi bir tasarımı olan Master Page kullanılmaktadır. Peki biz bu tasarımı değil de kendi tasarımımızı Master Page 'e taşımak istersek neler yapmamız gerekir. Gelin hep birlikte bunu incelemeye çalışalım.

Her zaman olduğu gibi ilk olarak yapmamız gereken Visual Studio 2008 SP1 geliştirme ortamında bir Asp.Net MVC Framework Web uygulaması oluşturuyoruz. Proje dosyasının içerisinden ilk olarak varsayılan olarak oluşturulan Master Page 'in yerini bulalım.



MVC tasarımını dikkate alarak araştırmalarımızı yaptığımızda görsel öğelerin view katmanında olduğunu görürüz. Master Page her yerde kullanılacak bir içerik olduğu içinde view içerisinde Shared klasörünün içerisinde yer alır.

Biz uygulamamızda bu otomatik olarak oluşturulan Master Page 'i kullanmak yerine kendimize bir tane oluşturalım. Ama ilk olarak oluşturulmuş olan Site.Master 'ı siliyoruz. Sonrasında da Add- NewItem yolunu izleyerek web sitesine yeni bir Master Page ekliyoruz.



Master Page 'i sorunsuzca projeye ekledikten sonra nasıl bir içerik oluşturulacağının düşünülmesinin zamanı gelmiştir. Basit olması açısında içeriğe göre değiştirilebilir iki sütun ekleyelim. Bu değişen içerik eklemeyi Asp.Net 'ten de alışık olduğu gibi <asp:ContentPlaceHolder> yardımı ile yapacağız. İçeriği arttırdıktan sonra temel CSS ile Master Page 'in içerisine stil özellikleri de ekliyoruz ve bu yaptığımız işlemler sonrasında elimizdeki değişikler aşağıdaki gibi olacaktır.

View\Shared\Site.Master
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
   <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>

   <style type="text/css">
      html
      {
         background-color:Gray;
      }

      .column
      {
         float:left;
         width:300px;
         border:solid 1px black;
         margin-right:10px;
         padding:5px;
         background-color:white;
         min-height:500px;
      }

   </style>
   <asp:ContentPlaceHolder ID="head" runat="server">
   </asp:ContentPlaceHolder>
</head>
<body>
   <h1>Sitem</h1>

   <div class="column">
      <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
      </asp:ContentPlaceHolder>
   </div>
   <div class="column">
      <asp:ContentPlaceHolder ID="ContentPlaceHolder2" runat="server">
      </asp:ContentPlaceHolder>
   </div>
</body>
</html>

Eklemiş olduğumuz içerik kontrollerini body 'nin içerisine <div> taglarının arasına yerleştiriyoruz. Ayrıca div taglarının sütün gibi hareket etmesi için stil özelliğine daha önceden hazırlamış olduğumuz column 'u tanımlıyoruz. Yaptığımız bu işlemler sonucunda Master Page 'in görünümü aşağıdaki gibi olacaktır.



Basit fakat bizlerin hazırlamış olduğu bir Master Page 'e sahip olduk.

Master Page 'i Kullanan View Sayfa Oluşturmak

Asp.Net uygulamalarında Master Page 'ten yararlanarak web sayfaları oluşturabilmemiz mümkündü. Bunun bize en büyük yararı oluşturmuş olduğumuz sayfalarda Master Pages üzerinde belirtmiş olduğumuz içerik kontrol alanlarının düzenlenebilmesi ve diğer taraflar üzerinde herhangi bir değişiklik yapmadan hazırlıyor olmamızdır. MVC Framework 'ten yararlanarak hazırlamış olduğumuz web sayfalarında da Master Page Asp.Net uygulamalarında olduğu gibi kullanılmaktadır.

View klasörünün içerisinde yer alan Home klasörünün üzerinde sağ tıklama sonrasında karşımıza gelen menüden Add - NewItem seçeneğine tıklayarak ekrandan MVC View Content Page i seçerek Master Page 'i kullanabileceği bir web sayfa oluşturmaya başlıyoruz.


Sayfa tipimizi seçip ekle dediğimizde hazırlamış olduğumuz Master Page 'ler den istediğimizi seçmek için bir ekran çıkacaktır.


Tamam dedikten sonra artık Master Page 'i kullanan bir web sayfası uygulamamızda oluşturulmuş olacaktır. Oluşturulan sayfanın arka plan kodları aşağıdaki gibi oluşturulmuştur.

View\Home\Index.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="ContentPlaceHolder2" runat="server">
</asp:Content>

Standart olarak projelere eklenmiş olan *.aspx sayfalardan farklı olarak HTML ve Body tagları yer almaktadır. Bu taglar Master Page de oluşturulduğu için yalnızca belirttiğimiz içerik kontrol alanları sayfada gözükmüştür ve sayfa içerisinde kullanıcılara göstermek istediğimiz içerikleri buralardan yayınlarız. Örnek olması açısında body taglarının içerisine eklemiş olduğumuz <asp:content> 'lerin içerisinde biraz değişiklik yaparak aldığımız sonuca hep birlikte çok atalım.

View\Home\Index.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
   İlk içerik kontrol alanı
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="ContentPlaceHolder2" runat="server">
   İkinci içerik kontrol alanı
</asp:Content>

Yaptığımız düzenleme sonrasında ekran değişikliğimiz aşağıdaki gibi olacaktır.



Yapılmış olan değişikler sonrasında web sayfamızın içeriği istediğimiz gibi olmuştur.

Master Page yardımı ile oluşturulan view sayfanın içeriğini düzenlemek

İlk olarak düzenleme yapağımız yer sayfamızın başlığı olacaktır. Oluşturmuş olduğumuz web sayfası internet tarayıcısında açıldığında pencerenin en üst kısmında yer alan bölümü düzenleyelim. Asp.Net ten ve diğer bütün web sayfası kodlama yapılarından alışık olduğumuz üzere title bölümünde belirtmemiz yeterli olacaktır.

Sayfamızın markup kod tarafında en üstte yer alan <Page> </Page> bölümün aralığının içerisinde yer alan title özelliğini değiştirerek sayfa başlığını sorunsuzca oluşturmuş oluruz.


Yapmış olduğumuz işlemi hazırlanmış olan Master Pages ile ilişkilendirerek tekrardan yapalım. Bu durumda ilk olarak oluşturulan Master Pages içerisine koyduğumuz içerik kontrol alanlarını hatırlamamız gerekir ve bir tane head bölümünün içerisine <asp:contentplaceholder> ekledik. Alana başlık, meta ve diğer birçok kriteri ekleyebilmemiz mümkündür. Bu özellikten yararlanarak aspx sayfasının içerisinde aşağıdaki değişiklikleri uyguluyoruz.

View\Home\Index.aspx
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
   <title>Başlık buraya yazılacak</title>
   <meta name="description" content="İçindekiler buraya" />
   <meta name="keywords" content="ana arama kriterleri buraya" />

</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
   İlk içerik kontrol alanı
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="ContentPlaceHolder2" runat="server">
   İkinci içerik kontrol alanı
</asp:Content>

Asp.Net uygulamaları ile uygulamadığımız tekniklerin birebir aynısıdır. Bu örneklerin bu kadar detaylı olarak gösterilmesinin sebebi Master Pages kavramının temel yapısının alışık olduğumuz Asp.Net Master Pages kavramından bir farkının olmadığını da göstermek amacıyladır. Yapmış olduğumuz işlemler sonrasında karşımıza gelen ekran görüntüsü aşağıdaki gibi olacaktır.



Yaptığımız işlemler sonucunda gayet başarılıyız. :)

Bu yazımızda Asp.Net MVC Framework ile hazırlanmış olan uygulamalarda Master Pages kavramını nasıl kullanabileceğimizi ve içerik düzenlemelerini nasıl kullanabileceğimizi detaylı bir biçimde incelemeye çalıştık. Bir sonraki MVC Framework yazımızda Master Pages kavramını incelemeye devam ederken veri tabanı işlemleri ile ilişkilerine de detaylı bir biçimde değineceğiz.

Umarım yararlı olabilmiştir.
info@turhaltemizer.com

Cuma, Mayıs 22, 2009

Asp.Net MVC Framework - Controller ve Action Kavramı

Asp.Net MVC Framework web projesi şablonunu incelerken başlattığımız yazı dizimize Controller katmanına daha detaylı değinerek devam ediyor olacağız.

MVC Framework ‘te en önemli parçalarından biride Controller ‘dır. MVC patterninde son kullanıcılar tarafında yapılan istekler doğrultusunda route map yardımıyla gerekli controller sınıfına yönlendirerek işlemleri gerçekleştirmeye başlatır. Controller üzerinde modelle ilişkili olarak veri tabanı işlemleri, yönlendirme işlemleri, hesap işlemleri gibi bir web sitesi için en temel işlemlerin yapıldığı katmandır.

Controller ‘ı Anlamak

Asp.Net MVC ‘ de kullanıcılar tarafında gelen istekleri alan işleyen ve geri ileten katman olarak tanımlayabiliriz. İnternet tarayıcısında parçalı olarak her controller için ayrı bir istek yapılır. Ufak bir örnek adres üzerinden değinmek gerekirse;

http://localhost/Urun/Index/7 başarılı bir gösterim olabilir.

Controller adı adres çubuğunda Urun olarak geçmektedir. Bu Controllers\ klasörünün alt dizininde yer alan UrunController.cs sınıfından gelmektedir. Bu sınıf gelen isteklere karşı gerekli sonuçları döndürmek için kullanılmaktadır. Controller ların bir diğer özelliği ise yapılan bir işlem sonrasında işlenecek daha parçalar var ise başka bir controller sınıfına aktarmaktadır.

Basit olarak UrunController.cs sınıfına göz atalım;

Controller\UrunController.cs
using System.Web.Mvc;
using System.Web.Mvc.Ajax;

namespace MvcApplication1.Controllers
{
    public class UrunController : Controller
    {
         //
         // GET: /Urun/

         public ActionResult Index()
         {
              // Add action logic here
              return View();
          }

     }
}

Harici olarak oluşturulan controller sınıfları System.Web.Mvc.Controller sınıfı miraslanarak oluşturulmaktadır. Ayrıca controller sınıflarında oluşturulan metotlarda en çok dikkatimizi çeken Action kullanımıdır.

Action ‘ı Anlamak

Controller sınıflarını daha da işlevsel kılan Action kullanımıdır. Son kullanıcıdan gelen istek doğrultusunda hangi işlemi yapacağını belirtilen controller sınıfında yer alan metodlar yani action ‘lar yapmaktadır.

http://localhost/Urun/Index/7 adres çubuğunda Urun kontrollerken Index/7 belirtilen meto da 7 parametresine göre işlem yapması anlamına gelmektedir.

Controller ‘ı incelerken vermiş olduğumuz kod bloğunu örnek olarak kullanırsak, UrunController sınıfında yer alan Index() metodunu action ‘dır. Action public metot olmalıdır. C# metodları varsayılan olarak private oluşturulmaktadır. Bu sebepten ötürü action metotlarının public olarak belirtilmesi gerekmektedir.

Action metotlarının aşırı yüklenmesi kabul gören bir kullanım biçimi değildir. Action özellikle daha özelleştirilmiş kullanıma odaklandığı için benzer metot isimleri ile birden fazla işlem yapılması çalışma zamanında sorunlara sebep olabilmektedir.

Action Result ‘ı Anlamak

Controller da kullanılan action lar action result ile geri dönüşleri vardır.

1. ViewResult: HTML ve Markup sunar (Represent).
2. EmptyResult: Sunumu sonlandırır.
3. RedirectResult: Sunulan linki yeni bir adrese yönlendirmeye yarar
4. JsonResult: Java Script Object ‘leri Ajax ile birlikte kullanılabilir bir duruma getirir.
5. JavaScriptResult: Java Script leri sayfada kullanılabilir biçimde sunar.
6. ContentResult: Metin içeriği sunar.
7. FileContentResult: İndirilebilir dosyaları sunar (Binary içerik ile).
8. FilePathResult: İndirilebilir dosyaları sunar (Dosya yolu ile).
9. FileStreamResult: İndirilebilir dosyaları sunar (Stream dosyalar için).
View result kullanılarak hazırlanmış bir metoda göz atalım.

Controller\KitapController.cs
using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
    [HandleError]
    public class KitapController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    }
}

Action sonucunda ViewResult ile HTML view ‘e dönecektir. Index() metodunda view adına göre geri dönüşü yapacaktır.

ViewResult() ve View() metotları Controller sınıfında türetilerek oluşturulmuştur. Controller ‘ın temel sınıfları;

1. View: Action sonucunda ViewResult ‘a yönlendirilir.
2. Redirect: Action sonucunda RedirectResult ‘a yönlendirilir.
3. RedirectToAction: Action sonucundan RedirectToRouteResult ‘a yönlendirilir (action yardımıyla yönlendirilir).
4. RedirectToRoute: Action sonucunda RedirectToRouteResult ‘a yönlendirilir (route yardımıyla yönlendirilir).
5. Json: JsonResult döndürür.
6. JavaScriptResult: JavaScriptResult döndürür.
7. Content: Action işlemi sonucunda ActionResult döndürür.

İnternet tarayıcılarında Controller üzerinde action çağırıldığında View() metodu kullanılmaktadır. Kullanılan bir diğer Action metodu ise RedirectToAction ‘dır. Bu metot yapılan işlemler doğrultusunda geri dönülmesi gerekiyorsa kullanılmaktadır.

Eğer ki Details metodunda ki id parametresine gelen değer HasValue ‘dan farklıysa bizim belirttiğimiz bir view HTML sayfaya yönlendirilmesini talep eden bir controller sınıfı hazırlayalım.

Controller\KullaniciController.cs
using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
    [HandleError]
    public class KullaniciController : Controller
    {
        public ActionResult Details(int? id)
        {
              if (!id.HasValue)
                   return RedirectToAction("Index");
              return View();
        }

        public ActionResult Index()
        {
            return View();
        }
    }
}

Şimdi vereceğimiz örnek ise içeriklerin gösterimi ile ilgili. Index metodunda ContentResult metodunu kullanarak belirtilen içerisi göstermektedir.

Controller\DurumController.cs
using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
    [HandleError]
    public class DurumController : Controller
    {
        public ActionResult Index()
        {
            return Content("Merhaba Dunya!!!");
        }
    }
}

İçeriği ContentResult metodu da bizim girebilmemiz dışında oluşturulan metotların geri dönüş değerlerine göre de otomatik olarak belirtilebilmesi mümkündür.

Controller\IsController.cs
using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
    [HandleError]
    public class IsController : Controller
    {
        public DateTime Index()
        {
             return DateTime.Now;
        }
    }
}

Index() metodunda action olarak DateTime nesnesini geri dönüş değeri almaktadır. İnternet tarayıcısında DateTime ‘ın geri dönüş değeri metin olarak View sayfada gösterilmektedir.

Controller Oluşturuyoruz…

Asp.Net MVC Framework ‘te Controllerları nerelerden nasıl ekleyebileceğimize ve detaylarını inceleyerek yazımıza devam ediyoruz. Bu işlemlerimizi Visual Studio geliştirme ortamı üzerinde örneklerimizi yapıyor olacağız.

Menü üzerinde Projeye Menü Eklenmesi

MVC Framework web projesi şablonu ile oluşturulmuş proje üzerinde yeni bir controller sınıfı eklemek için Controllers klasörünün üzerinde fare ile sağ tıklama ile Add->New -> Controller yolunu izleyerek ekleyebilmemiz mümkündür.



Sonrasında karşımıza controllerin adını gireceğimiz bir ekran çıkmaktadır.



Controller\PersonelController.cs
using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
    [HandleError]
    public class PersonelController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    }
}

Action Metotunun İskeleti

Biraz önce anlattığımız gibi kolay bir şekilde controller sınıfı ekleyebilmemiz mümkündür. Anlattığımız temel işlemlerin dışında bir de Create, Update ve Details Action metotlarını da basitçe ekleyebilmemiz mümkündür. Sadece yapmamız gereken Controller adını verdiğimiz ekranda senaryolarında oluşmasını isteyip istemediğimizi soran bölüme onay vermek olacaktır.



Seçeneği onaylayığ UrunController sınıfını ekle dediğimizde aşağıdaki sınıfı bize Visual Studio otomatik olarak oluşturmaktadır.

Controller\UrunController.cs
using System.Web.Mvc;
using System.Web.Mvc.Ajax;

namespace MvcApplication1.Controllers
{
    public class UrunController : Controller
    {
        //
        // GET: /Urun/

        public ActionResult Index()
        {
            return View();
         }

         //
         // GET: /Urun/Details/5

         public ActionResult Details(int id)
         {
             return View();
         }

         //
         // GET: /Urun/Create

         public ActionResult Create()
         {
             return View();
         }

         //
         // POST: /Urun/Create

         [AcceptVerbs(HttpVerbs.Post)]
         public ActionResult Create(FormCollection collection)
         {
             try
             {
                   // TODO: Add insert logic here

                  return RedirectToAction("Index");
              }
              catch
              {
                  return View();
              }
          }

          //
          // GET: /Urun/Edit/5

          public ActionResult Edit(int id)
          {
               return View();
           }

           //
           // POST: /Urun/Edit/5

          [AcceptVerbs(HttpVerbs.Post)]
          public ActionResult Edit(int id, FormCollection collection)
          {
              try
              {
                   // TODO: Add update logic here

                   return RedirectToAction("Index");
              }
              catch
              {
                     return View();
               }
          }
     }
}

Oluşturulan sınıf yardımıyla Index, Details, Update, Edit gibi temel veri tabanı işlemleri daha hızlı hazırlayabilmemize olanak tanır.

Controller Sınıfı Oluşturmak

Şu ana kadar sürekli olarak ya daha önceden oluşturulmuş olan controller sınıflarını inceledik ya da Visual Studio yardımıyla kolayca oluşturduk. Şimdi ise boş bir sınıf oluşturarak kendimiz bir controller sınıfı nasıl oluşturabileceğimizi incelemeye çalışalım.

Visual Studio ‘da controllers sınıfına sınıfımızı el ile ekliyoruz. Şimdi yapacağımız adımlara bir göz atalım.

1. Controllers klasörüne bir sınıf ekliyoruz.
2. Eklemiz olduğumuz sınıfın adı muhakkak Controller ile bitmelidir.
3. Sınıfı düzenlerken System.Web.Mvc.Controller ile miraslaşması gerekmektedir.

Bu işlemleri tamamladığımızda kendimiz sorunsuzca bir controller sınıfı oluşturmuş oluruz.



Controller\YaziController.cs
using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
    [HandleError]
    public class YaziController : Controller
    {
        public string Index()
        {
            return "Merhaba Dunya!!!";
        }
    }
}

Index() metodunu internet tarayıcısı üzerinde çağırmak istediğimizde http://localhost:40700/yazi adresini belirtmeniz yeterli olacaktır. Bize Merhaba Dünya!!! Sonucunu döndürecektir.

Not: localhost:40700 ‘deki 40700 port numarasıdır. Bu numara her yeni bir Asp.Net Development Server oluşturulduğunda birbirinden farklı bir biçimde oluşturulabilir. Eğer değişmesini istemiyorsanız projenin özelliklerinden statik olmasını sağlar ya da web sayfanızı localhost altına alıp hiç port numarasına gerek kalmadan kullanabilirsiniz.

Action Oluşturuyoruz…

Yazımız boyunca controller sınıflarının ne işe yaradığını detaylı bir şekilde öğrendik. Şimdi ise yeni bir controller action nasıl oluşturulur, özellikleri nelerdir incelmeye çalışıyor olacağız.

Controller sınıfları içerisinden gelen istekler doğrultusunda işlemler action metotları ile gerçekleştirilir. Şimdi action metotlarının nasıl oluşturulabildiğini incelemeye çalışalım.

Controller Action Ekliyoruz…

HomeController sınıfının içerisine Index() action metodunun dışında birde MerhabaDe() action metodunu oluşturuyoruz. Şimdi bu değişikliği hemen yapalım. J

Controller\HomeController.cs
using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public string MerhabaDe()
        {
            return "Merhaba";
        }
    }
}

Action metot oluştururken dikkat etmemiz gereken kriterler aşağıdaki gibidir.

• Bu metot public(genel) olmalıdır .
• Metot statik olamaz.
• Metodun bir uzantısı olamaz.
• Metoda ilişkin bir yapıcı, alıcı ya da verici olamaz
• Metotta açık genel türleri olamaz.
• Bu metot controller temel alınarak hazırlanmış bir metot değildir.
• Metot parametreleri Ref veya out içeremez.

Controller action metotları geri dönüş değerleri olarak string, DateTime gibi tipleri alabilirler. Asp.Net MVC Framework string olmayan bir action metot parametresini tarayıcı tarafında string değer gönderildiği durumlarda dönüştürme işlemini yapamaz ve hata mesajı verir.

Action metotlarda kullanılacak parametrelerde boş değer de gelme olasılığını düşünerek tipler nullable olarak belirlenir.

Genel bir action metodu oluşturalım. Fakat bu oluşturma işleminde bu metoda action değilsin diyerek bir de çelişkiye sebep olduralım. Bu durumda controller ı ve action adının çağırdığımız durumda bize nasıl bir tepki vereceğine hep bir birlikte bir göz atalım.

Controller\SirketController.cs
using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
    [NoAction]
    public class SirketController : Controller
    {
        public string SirketSirri()
        {
            return "Bu bilgi şirket sırrıdır.";
        }
    }
}

İnternet tarayıcımızda Sirket/SirketSirri yazarak action metodumuzu çağırdığımızda nasıl bir tepki ile karşılaşacağımıza göz atalım.

Gördüğünüz üzere Sirket controlleri ve SirketSirri() metodu olduğu halde bize isteğiniz bulunamamaktadır gibi hata mesajı vermektedir. Bunun sebebi Action metodumuzun başına sen action değilsin dememizden kaynaklanmaktadır.

Bir yazımızın daha sonuna geldik. Bu yazımızı da Controller sınıflarını ve action metotlarını detaylı bir biçimde incelemeye çalıştık.

Herkese mutlu günler diliyorum.

Cumartesi, Temmuz 19, 2008

Silverlight 2.0 - Kontrollerin Özelleştirilmesi, VSM ve Yenilikleri

Microsoft, Silverlight ‘ı gün geçtikçe benzersiz bir yapı haline dönüştürüyor. Günler geçtikçe kontroller, aspx desteği derken Asp.Net ‘te pek alışık olmadığımız bir durum olan kontrollerin özelleştirmesi özelliği Beta2 sürümü ile eklenmiş olduğunu gözlemleyebiliyoruz. Peki, Silverlight bugüne gelene kadar ne tür gelişmeler gösterdi.

Alpha1 sürümünde JavaScript ve HTML ile interaktif web uygulamaları geliştirebiliyorduk.
Alpha2 sürümü ile yukarıdakilere ek olarak XAML ‘de eklendi.
Beta1 sürümünde WPF ‘te kullanılan kütüphane kısmen geçirilmeye başlandı.
Silverlight 1.0 sürümünde yukarıda bahsettiğimiz deneme işlemleri uygulanabilir düzeye getirildi.
Silverlight 1.1 sürümünde buton gibi temel kontroller Silverlight bünyesine eklendi.
Silverlight 2.0 Beta1 ile web servis işlemlerinden veri bağlamaya kadar bir çok özellik eklendi fakat en çok dikkat çekeni kullanılabilir Silverlight kontrolü sayısı arttırıldı.
Silverlight 2.0 Beta2 sürümü ile ise Beta1 sürümünden eklenen bir çok özellik geliştirildi. Asya dilleri eklendi. En çok göze çarpan özelliği ise Expression Blend ürünü ile Silverlight kontrollerinin düzenlenebilmesi olmuştur.

Silverlight ‘ın günümüze kadar geçirmiş olduğu gelişim temel olarak bu şekildedir. Tabii saydığımız özelliklere ek olarak video streaming özelliği en popüler olanıdır. Videoların gösterilme süreleri o kadar iyileşti ki web üzerinden canlı yayınlar yapılabildi ve HD videoların fragmanları sorunsuz bir biçimde kullanıcılara izletilebildi.

Eski sürümlerde neler yapabildiğimiz ile ilgili ayrıntılı bilgilere ulaşmak isterseniz daha önceden yayınlanmış olan makaleleri okumanızı öneririz.

Silverlight 2 Beta2 ile uygulama geliştirebilmeniz için http://www.microsoft.com/downloads/results.aspx?pocId=&freetext=silverlight%202%20beta2&DisplayLang=en adresinden gerekli bileşenleri bilgisayarınıza indirdikten sonra kurarak kullanmaya başlayabilirsiniz. Ayrıca yazımızda kontrollerin özelleştirilmesi işlemleri Expression Blend 2.5 June Preview ile yapacağız. Bu programı kullanabilmeniz için gerekli link ise http://www.microsoft.com/downloads/results.aspx?pocId=&freetext=expression%20blend%202.5%20june%20preview&DisplayLang=en adresinden yararlanabilirsiniz. Gerekli programları edindiğimize göre artık yazımızın içeriğini incelemeye başlayabiliriz.

KULLANICI KONTROLLERİ
Silverlight ilk sürümlerinde WPF ‘e yetişmesi uzun yıllar alacağı konusunda söylentiler varken şu anda WPF ‘te bile olmayan kontrolleri bünyesinde barındırmaktadır. Özellikle DataGrid kontrolü WPF ‘te olmadığı halde Silverlight 2.0 Beta2 ‘de yerini almıştır.



Bu ve diğer kontrollere ek olarak TabPanel kontrolü de Beta2 sürümü ile bizlerin kullanımına sunulmuştur. Şu an itibari ile Silverlight2 Beta2 sürümünde 30 ‘ün üzerinde kontrol bulunmaktadır. Geliştiricileri tarafından yapılan açıklamada ise 2.0 sürümü tamamlandığı zaman 100 ‘ün üzerinde kontrolün bizlere sunulacağı belirtilmiştir.

Kontrollerin Özelleştirilmesi
WPF ve Silverlight ile son kullanıcılar için hazırlanmış olan kontroller Expression Blend yardımı ile özelleştirilebilmektedir. Özelleştirdiğimiz kontrolleri daha sonrasında geliştirmiş olduğumuz uygulamada XAML kod tarafına ekleyerek kullanılabilir düzeye getirilebilmesi mümkündür.

Şimdi Expression Blend yardımı ile kontrolleri nasıl özelleştirebileceğimize göz atalım. Bu işlemi yaparken ilk olarak slider kontrolünden yararlanacağız.

İlk olarak Expression Blend 2.5 June Preview ’den Silverlight 2 projesi oluşturuyoruz. Sonrasında ise uygulama ekranımıza bir tane slider kontrolü ekleyerek işlemlerimize başlıyoruz.



Slider kontrollerini ekledikten sonra şimdi düzenleme işlemini gözlemleyeceğiz. İlk olarak yapmamız gereken kontrolün üzerinde fare ile sağa tıkladıktan sonra çıkan menüden Edit Control Part ‘ı seçeceğiz. Sonrasında çıkan seçenekten Edit a Copy seçeneğine tıklayarak işlemimizi yapmaya devam edeceğiz.



Bu seçeneği seçtiğimizde karşımıza aşağıdaki gibi ekran gelecektir.



Karşımıza çıkan ekranda Name(Key) yazan bölüme istediğimiz ismi verdikten sonra tamam diyerek slider kontrolünü özelleştirebilmemiz mümkündür. Bu verdiğimiz isim app.xaml ‘in içerisinde tutulur ve daha sonradan yapacak olduğumuz işlemleri bu isim altında tutar ve kullanacağımız zaman arka planda bu name ‘i kullanacaktır.

Kontrolü özelleştirebilmemiz için sol tarafta yer alan menüde Template yazan bölümden yararlanacağız. Bu tasarı bölümü bizlere hazırlanan kontrolün hangi nesnelerin toplanması sonucunda oluşturulduğunu göstermektedir. Tasarı bölümünde yer alan ilk dörtgen bölümünde çizginin kalınlığı uzunluğu ve kaydırma butonunun yapısı ile ilgili özellikler tutulmaktadır. Diğerinden ise dikey özellikler yer almaktadır.



Temel olarak bir değişiklik yapmak gerekirse HorizontalThumb ‘ı seçerek uygulamamın çalışma ekranında kaydırma çubuğunun kalınlığını değiştiriyoruz. Sonucunda ise ekranımızda oluşan görüntü aşağıdaki gibi olur.



Gördüğünüz gibi oldukça kolay bir biçimde kontrolleri özelleştirebilmemiz mümkündür. Bu yaptığımız işlemleri uygulayarak diğer bütün kontrolleri de özelleştirebilmemiz mümkündür.

Visual State Manager (VSM) Yapısı
Silverlight ve WPF ‘te hazırlamış olduğumuz kontrollere standart kontrollerden farklı olması için özel işlemler uygulamak isteriz. Örneğin, fare ile kontrolün üzerinde gelindiğinde tıklandığında gibi işlemler sonucunda farklılıkların olmasını isteyebiliriz. Gerçekleştirebilmek için ise yapmamız gereken XAML kod tarafında oldukça fazla kod oluşturan animasyon işlemlerini kullanırız. Arka planda oluşturulan fazla satır kodlar ise kontrol kullanılacağı sırada çağırılacağı için web uygulamalarında yani Silverlight uygulamalarında yavaş çalışmasına sebep olabilir. Web uygulamalarında yaşanabilecek sorunları engellemek için farklı bir çözüm üretilmesi gerekiyordu ve bunun için Visual State Manager (VSM) hazırlanılmış ve biz geliştiricilere sunulmuştur.

VSM, standart olarak hazırlanmış olan kontrolleri özelleştirme işlemimiz ile birlikte fare ile ilgili standart özellikleri de yapılandırabilmemize olanak tanımaktadır. Bizlere kazandırdığı en büyük avantaj ise daha önceden hazırlanmış olan bir animasyon işleminin yeniden düzenlenebilmesi oldukça uğraştırırken VSM kullanarak hazırlanmış olanlar dinamik olarak düzenlenebilmesi mümkündür.

Şimdi VSM ‘i örnek üzerinden incelemeye çalışalım.

Expression Blend ile Silverlight 2 uygulaması açtıktan sonra çalışma ekranımıza bir adet buton sürükleyip bırakıyoruz.



Eklemiş olduğumuz butonun üzerine sağ tıklama yaparak karşımıza çıkan menüden Edit Control Part ‘ı seçiyoruz. Karşımıza çıkan menüden Edit a Copy ‘ı seçerek işlemimizi yapmaya devam ediyoruz.



Edit a Copy seçeneğini tıkladığımız zaman bize aşağıdaki gibi bir ekran çıkmaktadır.



Kontrollerin özelleştirilmesi konusunda da değindiğimiz gibi vermiş olduğumuz name app.xaml içerisinde tutulacak ve kontrol üzerinde yapacak olduğumuz işlemlerin kullanılması için gerekli olan name çağırılması işleminin yapılmasını sağlıyoruz.

Bu işlem sonrasında asıl konumuz olan VSM için gerekli olan state menüsü sol bölümde karşımıza gelmektedir.



State bölümünde Base seçili iken buton kontrolümüzün arka plan ve kenar renklerini değiştireceğiz. Bunun için Template bölümünde Background ve BackgroundGradient özelliklerini değiştireceğiz.



Yaptığımız değişiklik sonucunda butonumuz aşağıdaki gibi olmuştur.



Fare üzerinde gibi özellikleri değiştirmek istediğimizde ise State bölümünde MouseOver seçeneğine ait özelliği değiştirdiğinizde işlemimizi gerçekleştirmiş oluruz.



Temel olarak VSM tasarımcılar ile web geliştiriciler arasındaki uyumu arttıracak ve hazırlanan tasarımların tam anlamında kullanılabilmesine olanak tanıyacak bir özelliktir.

Textbox
Textbox kontrolünde ve genel olarak yazı yazılabilecek bütün kontroller için IME3 adı verilen Asya ve diğer farklı yazım türü olan karakterler eklenmiştir.



Animasyon ve Grafik Sistemi
Silverlight ile hazırlanmış olan animasyon uygulamaları web tarayıcılarda gösterildiğinde çalıştırılan bilgisayarın grafik sisteminde zorlamaya sebep olmaktaydı. Bunun sebebi ise Silverlight, WPF tabanlı olduğu için animasyon uygulamaları çalıştırırken grafik kartının sürücüsünü kullanmak istemektedir. Fakat bu bir web uygulaması için performans yavaşlatıcı bir durumdur. Grafik kartını zorlama oranı beta2 sürümü ile iyileştirilmiş. Tam sürümünde ise zorlama oranının en minimum düzeye getirileceği Silverlight geliştiricileri tarafından açıklanmıştır.

WPF ile uyumu
Silverlight ‘ın gelişimi WPF ‘e oranla daha hızlı olduğu için şu anda aralarında ki uyum azalmış giib gözüküyor. .Net Fw 3.5 Sp1 çıktıktan sonra ise Silverlight ‘ta yapılan değişikler WPF ile uyumlu hala getirilerek XAML kod tarafında yazılan uygulamaların iki platformda da belirli oranda çalışması sağlanacak.

Web Servis
Silverlight ‘ta daha önce SOAP ile web servisi kullanılması mümkündü. Fakat Beta2 sürümü ile WCF servislerinin kullanımı mümkün hal almıştır.

Veri (DATA)

Data Grid
Beta2 sürümünde eklenen bu kontrol de sayfanın boyutuna göre otomatik şekillendirilme, sütunlarda yer alan sonuçların sıralanabilmesi gibi özellikler mümkün kılınmıştır.

NOT: WPF ‘te şu an itibari ile DataGrid kontrolü bulunmamaktadır. .Net Framework 3.5 Sp1 ile ekleneceği düşünülmektedir.

Data Binding
Hataların, zengin içerikli yazıların bağlanabilmesi gibi özellikleri bünyesinde barındırmaktadır.

Silverlight ‘ın gelişimi

Silverlight gün geçtikçe yalnızca animasyon yapabildiğimiz ve video yayınlayabildiğimiz bir yapı olmaktan çıkarak son kullanıcılar için oldukça zevkli uygulamalar geliştirilebilecek, Asp.Net ‘te yapabileceğimiz bir çok işlemi yapabileceğimiz bir yapı olma yolunda ilerlemektedir. Silverlight 2.0 sürümü tamamlandığı zaman web uygulamalarında birçok yazılımcı Asp.Net yerine Silverlight ‘ı deneyecektir. Çünkü kullanıcılara sunduğu zevk ve kolaylık Asp.Net ‘e göre daha fazla olacaktır.

Sonuç olarak yazımızda nelere değindiğimizi hatırlamak gerekirse, Silverlight ‘ın bugüne kadar geçirdiği değişime değindikten sonra kontrollerin özelleştirilmesine, VSM ‘e , Silverlight 2.0 Beta2 ‘de genel özellikler yönünde ne tür değişiklikler yapıldığını ve son olarak da Silverlight ‘ın geleceğe dair gelişiminde ne tür gelişmeler yaşanabileceğine değinmeye çalıştık.

Umarım yararlı olmuştur.

Turhal TEMİZER

Kaynaklar
Silverlight.Net

Cuma, Temmuz 18, 2008

XML (Extensible Mark-up Language)

XML’e Giriş

XML (Extensible Markup Language), W3C (Worl Wide Web Consortium) tarafından geliştirilen bir kaynak hazırlama standartıdır.
XML aslında SGML (Standart Generalized Markup Language) adlı daha geniş ve kapsamlı bir standardın alt kümesi sayılabilir. 1980’den beri var olan SGML çok kapsamlı ve karmaşık yapısıyla bazı zorluklar içeriyordu. XML bu karmaşayı mümkün olduğunca azaltmak ve uygulama kolaylığı sağlamak amacıyla geliştirildi.
XML bir dil olmaktan çok bir dil tanımlama aracıdır. Bu standartı kullanarak kendi dilinizi üretebilir, kendi kurallarınızı koyabilirsiniz.
HTML ile XML aynı şey değildir. HTML’in önceden belirlenmiş kuralları vardır ve HTML ile yazılan bir döküman bu kurallara uymak zorundadır. Mesela <BODY> ve <HEAD> gibi imler HTML’de önceden tanımlıdırlar; bunları değiştiremezsiniz. Fakat XML’de imleri siz tanımlarsınız. Bu sayede <BuyukBaslik>, <KucukBaslik>gibi imler tanımlamanız mümkün olabilir.
XML dokümanlarında elemanlar aşağıdaki gibi yazılırlar:

<Paragraf>
Bu ilk paragraf
</Paragraf>

Yukarıdaki eleman iki im’in arasına yazılmıştır. ˙Imler <ve > sembolleri arasında yazılırlar. Bir im’in etki alanını bitirmek, bir başka deyişle bir im’i kapatmak için / sembolü kullanılır.
Elemanlara bazı özellikler atanabilir.

<Para kur="dolar">34.25</Para>

Bu örnekte <Para>adlı imin kuradlı bir özelliği olduğu anlaşılıyor. XML’de boş elemanlar tanımlanabilir. Buna örnek vermek gerekirse;

<Resim kaynak="/home/user/resim.gif"></Resim>

veya

<Resim kaynak="/home/user/resim.gif"/>

XML’in bazı kurallarından bahsedelim:

· Elemanların özellikleri her zaman tırnak işaretleri içerisinde tanımlanmak zorundadır.

        <Yazi tip="italik">Maslak</Yazi>

· Boş elemanlar hariç bütün elemanlar açma ve kapama imleri arasına yazılmak zorundadır. Bu kurala göre aşağıdaki satırlar XML kurallarına uygun değildir.

·         <Paragraf>Ilk paragraf
·         <Paragraf>Ikinci Paragraf
·         Doğrusu şöyle olmak zorundaydı
·         <Paragraf>Ilk paragraf</Paragraf>
·         <Paragraf>Ikinci Paragraf</Paragraf>

· Içiçe geçen imler doğru yapılmalıdır. Bu kurala göre aşağıdaki tanımlama yanlıştır.

·         <Kalin><italik>Bu satır yanlış</Kalin></italik>

Doğrusu şöyle olmalıydı

<Kalin><italik>Bu satır do¸gru</italik></Kalin>

Yukarıdaki 3 kural XML kullanıcılarının en yaygın olarak çiğnedikleri kurallardır.

Bunun kaynağı ise HTML kullanma alışkanlığıdır. Tarayıcı (Browser) üreticilerinin yazım hatalarını mümkün olduğunca tolere edebilme kaygısı yüzünden kurallara uygun olmayan HTML dökümanları sanaldoku üzerinde sorunsuz yayımlanabilmektedir. Ancak bu kaygı, beraberinde karmaşık yazılımları gerektirdiği için tarayıcıların dökümanları işleme hızlarında dikkate değer bir düşüş yaşanmaktadır.

Bir XML dökümanı sözkonusu olduğunda 3 önemli dosya gündeme gelir.

· XML kaynak dökümanı

· stylesheet’ denilen, dökümanın herhangi bir yayım aracında nasıl gör üneceğini belirleyen dosya .

· XML kaynağının kurallarının yazıldığı DTD adlı dosya. DTD (Document Type Definition) dosyası XML dosyası içinde kullandığınız imlerin tanımlarının yapıldığı dosyadır .

örnek

<?xml version="1.0" standalone="no"?>
<!DOCTYPE Dunya:Turkiye SYSTEM "sample.dtd">
<!-- XML dokumani burada basliyor -->
<Dunya:Turkiye xmlns:Dunya='http://www.Dunya.com/'>
<Dunya:Insanlar>Duygu Caglar</Dunya:Insanlar>
<Dunya:Yas>21</Dunya:Yas>
</Dunya:Turkiye>

Ilk satırda <?xml ve ?> arasında kalan kısım temel tanımların yapıldığı yerdir. versionXML dökümanının versiyonunu belirtir. standaloneseçeneği XML dökümanının dışarıdan verilecek bir DTD dosyasına ihtiyacının olup olmadığını belirler. standalone=”no” buyruğu dökümanın kendisini tanımlayabilmesi için bir DTD’ye ihtiyac duyduğunu söyler. Bu örnekte ihtiyaç duyulan dosyanın sample.dtdadlı dosya olduğu ayrıca belirtiliyor. Aslında DTD ve stylesheet dosyalarını XML dökümanının içine gömmek mümkündür. Ama genelde tercih edilen bir yöntem değildir .

<!DOCTYPE Dunya:Turkiye SYSTEM "sample.dtd">

satırı dökümanın kök elemanını ve kök elemanı içerisinde yazılacak bütüm imlerin tanımlarının yer aldığı DTD dosyasını belirler. Bizim örneğimizde dökümanın kök elemanı Dunya:Turkiye adlı elemandır. SYSTEM anahtar sözc üğü ise DTD dosyasının ayrı bir yerel dosya içerisinde bulunduğunu belirtir.

<!-- ve -->sembolleri içerisinde yer alan bütün cümleler yorum olarak algılanır ve XML yorumlayıcıları tarafından ihmal edilir. Son olarak Dunya:Turkiye,Dunya:Insanlarve Dunya:Yas imlerini kullandık. C¸ oğu XML imi gibi bunlar da kendilerini tanımlayan DTD'ler olmadan anlamsızlardır. Bu imler görüldüğü gibi iki parçadan oluşmaktadır.

Parçalar arasında : sembolü kullanılmış. Bunun sebebi im adlarını seçerken alanadı kullanmamızdır: sembolünün sol tarafı alanadı'nı, sağ tarafı ise imin kendisini ifade eder

Alanadı kullanımı XML dünyasında yeni kullanılmaya başlamıştır. Kabaca im tanımlarının karışmaması için tasarlanmıştır. Örnek vermek gerekirse; Dunya:Turkiye yerine Turkiye imini kullansaydık ve başka bir yayıncı da Turkiye imini kullansaydı, iki üreticinin ürettikleri dökümanları ortak olarak 6 kullanmaları mümkün olamazdı. Alanadları xmlnsanahtar sözcüğü ile belirtilir.

Eşsizlik sağlası amacıyla alanadları olarak genellikle sanaldoku yörelerinin adları kullanılır. Bizim verdiğimiz örnekte http://www.Dunya.com alanadı olarak kullanılmış. Alanadı olarak sanaldoku sayfalarını kullanmanın bir diğer faydası ise kullanılan XML dökümanı ile ilgili dosyaların herkes tarafından bilinen bir yere konulabilmesine imkan tanımasıdır. Buraya XML’i tanımlayan DTD dosyaları konulabileceği gibi, bazı stylesheet dosyalarıda konulabilir. Son olarak eklenmesi gereken bir nokta ise şudur; ilerleyen zamanlarda tarayıcıların XML programlarını istenilen ölçüde tanımaları durumunda ilgili dökümanlar on-line olarak işlenebilecektir. Tarayıcı bir XML dökümanı ile karşılaştığında onu tanımlayan DTD’yi ilgili yerden çekecek ve varsa stylesheet dosyasını kullanarak görüntüleyecektir.

DTD (Document TypeDefinition)

Bu bölümde DTD kavramını kabaca bir örnek üzerinden anlatmaya çalışaca ğız. Örnek DTD dosyası aşağıda verilmiştir.

<!-- Örnek bir DTD dosyası -->
<!ELEMENT Dunya:Turkiye (Dunya:Insanlar, Dunya:Yas)>
<!ELEMENT Dunya:Insanlar (#PCDATA)>
<!ELEMENT Dunya:Yas (#PCDATA)>

Bu DTD dosyasının amacı bir önceki bölümde yazdığımız XML kaynağını tanımlamaktır. <!ELEMENT buyruğu XML dökümanı içerisinde kullanılan büt ün imleri tanımlamak için kullanılır. Dunya:Insanlar ve Dunya:Yas imleri Dunya:Turkiye iminin içerisinde ve belirlenen sıra ile kullanılmak zorundadır .

Bu iki im’e Dunya:Turkiye iminin çocukları denir.

Dunya:Insanlar ve Dunya:Yas imlerinin tanımlarında ise #PCDATA sözcüğü kullanılmıştır (PCDATA=’Parsed Character Data’). Bunun anlamı Dunya:Insanlar ve Dunya:Yas imleri arasında < ve & hariç bütün karakter veya karakter kümesini kullanabilirsiniz. Mesela <Dunya:Insanlar>Dunya Turkiye</Dunya:Insanlar> satırı doğru bir XML satırıdır .

XSL (Extensible Stylesheet Language)

Yazdığımız DTD ile XML dökümanını tanımlamış olduk. Bu çerçeve içinde elimizdeki dökümana doğru tanımlanmıştır (valid) diyebiliriz. Ancak dök ümanın görüntülenişi hakkında hiçbirşey yapmadık. Bu iş için stylesheet kullanmamız gerekecek. Stylesheet olarak şu an yaygın olarak kullanılan CSS (Cascading Style Sheet) aracını kullanabilirsiniz. CSS daha çok HTML dökümanlarını biçimlendirmek için kullanılmakla birlikte XML’i de desteklemektedir.

Biçimlendirme için kullanılabilecek ikinci bir araç ise XSL (Extensible StyleSheet Language) adı verilen ve kendinize özgü stylesheet kodları oluşturabilmenize olanak sağlayan dildir. XML kullanmamızın sebebi yanlızca sanaldoku olmadığı için biz XSL kullanmayı tercih edeceğiz. Bu bölümde XSL kavramını kabaca bir örnek üzerinden anlatmaya çalışacağız. Örnek XSL dosyası aşağıda verilmiştir.

<?xml version="1.0"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/TR/WD-xsl"
xmlns:fo="http://www.w3.org/TR/WD-xsl/FO">
<xsl:template match="/">
<fo:block font-size="18pt">
<xsl:apply-templates/>
</fo:block>
</xsl:template>
</xsl:stylesheet>

Bu örnekte dikkati çeken ilk şey bir XSL dosyasının aynı zamanda düzgün tanımlı bir XML dökümanı olmasıdır. XML dökümanını biçimlendirecek buyruklar <xsl:stylesheet> ve </xsl:stylesheet> imleri arasında yer alırlar. Genel olarak bakıldığında XML dökümanı içerisinde yer alan imlerin formatları <xsl:template> ve </xsl:template> imleri arasında tanımlanır.

<xsl:template match="/">

Yukarıdaki satır, / ile belirtilen im için bir şekil tanımlar. /sembolü kök elemana karşılık gelir. Bizim örneğimizde kök eleman Dunya:Turkiye idi. Bizim XSL örneğimize göre kök elemanı içerisindeki yazıların font büyüklükleri 18pt olmak zorunda.

Bu XSL dosyasını XSL yorumlayıcılarından birinden geçirirsek XML dosyasının görüntüsünü elde edebiliriz.

Bir XML dökümanının doğru olması için gereken şartlar:

· Bir XML dökümanı ya DTD kullanmalı ya da dökümanın başında <?xml version="1.0" standalone="no"?> deklerasyonu yer almalıdır.

· Elemanların bütün özellikleri çift tırnaklar içinde belirtilmelidir.

· Bütün elemanlar açma ve kapama imleri arasında yazılmalıdırlar.

· Boş bir im kullanılacaksa im’in bitiminden önce \ işareti kullanılmalıdır.

·         <Resim kaynak="duygu.jpg"/>

Bazı XML buyrukları

<?xml...?>
<?xml version="number"
[encoding="encoding"]
[standalone="yes[no]"] ?>

version XML dökümanının versiyonu gösterir ve kesinlikle yazılması gerekir. encoding Kullanılacak karakter kümesini belirtir US-ASCII, iso-8859-1 gibi. standalone Eğer ’no’ ise, dökümanı tanımlayan bir DTD belirtmek zorunludur. Bunun için <!DOCTYPE> buyruğu kullanılır.

<!DOCTYPE>
<!DOCTYPE root-element SYSTEM|PUBLIC
["name"] "URI_of_DTD">

Bu buyruk XML dökümanını tanımlayan DTD kaynağını belirtmek için kullanılır. İki şekilde kullanılılabilir.

<!DOCTYPE root-element SYSTEM "URI_of_DTD">
<!DOCTYPE root-element PUBLIC "name" "URI_of_DTD">

SYSTEM DTD dökümanının yerini belirtir.

<!DOCTYPE <Book>
SYSTEM "http://www.domain.com/dtd/mydoctype.dtd">

PUBLIC Eğer kullanılan DTD çok büyük bir yaygınlık kazandı ise özel bir isimlendirme şeması kullanılır. XML işlemcisi bu tanımı gördüğü zaman ilgili DTD kaynağını sistemde kayıtlı olduğu yerlerden bulmaya çalışacaktır. Eğer ilgili dosyayı bulamaz ise SYSTEM buyruğu ile tanımlanmış DTD’yi kullanacaktır.

<!DOCTYPE <Book> PUBLIC
"-//Dunya/DTD/EN"
"http://www.Dunya.com/dtd/xmlbk.dtd">
<![CDATA[...]]>

XML dilinde özel anlamları bulunan karakterleri özel anlamları haricinde kullanmaya yarar. ’...’ ile belirtilen yere yazılan herşey XML işlemcisi tarafından salt metin olarak algılanacaktır

<![CDATA[
Burada XML dilinde özel anlamları bulunan karakterleri
bir problem olmadan rahatça kullanabiliyorum. Meselâ
<?xml version="3.145678"?> yazmam bir hata mesajı
üretmeyecektir.
]]>
<!--....-->

XML dokümanı içerisine bazı açıklamalar veya yorumlar yazabilmemizi sağlar.

XML’e Has Özelikler

xml:lang
xml:lang="iso_639_identifier>

xml:lang özeliği bütün elemanlar için kullanılabilir. Elemanın hangi dilde yazıldığını belirtmek için kullanılır.

<Paragraf xml:lang="en">Hello</Paragraf>
<Paragraf xml:lang="fr">Bonjour</Paragraf>

xml:space

xml:space="default|preserve"

Elemanın içerisinde yer alan boşluk veya tab karakterlerinin dikkate alınıp alınmamsını belirler. Eğer ’preserve’ seçeneği kullanılırsa boş ve tab karakterleri dikkate alınacaktır.

xml:link
xml:link="link_türü

Elemanın bir link olduğunu belirtmek için kullanılır.

Özel Karakterler

XML’de özel manaları bulunan karakterleri ifade edebilmek için değişik bir metod kullanılır. XML’de yaygın olarak kullanılan 5 özel karakter şöyle gösterilir.

· & &

· < <

· > >

· " "

· ' '

Kolaylıkla görüleceği gibi özel karakterleri ifade etmek için & ve ; işaretleri beraber kullanılır.

DTD ˙Içinde Eleman Tanımları

XML dökümanı içerisinde kullandığınız elemanların tanımlarını DTD dosyaları içerisinde yapmak zorunluluğu vardır. Bunun için şu kalıp kullanılır.

<ELEMENT eleman_ismi kural>

Eleman isminin içerisinde < ve > karakterleri olmamalıdır. Eleman isimleri karakter veya _ sembolü ile başlamalıdır. Ayrıca eleman isimleri xml ile başlamamlıdır. Bu son kurala uyulmaması aslında ciddi bir probleme yol açmayabilir. Ancak xml sözcüğü ile başlayan ve XML yapısı içerisinde özel anlamları olan bir takım imler bulunmaktadır. Bu imlerde çakışma olasılığı bulunduğundan ötürü bu kısıtlamaya uyulması çok yerinde olacaktır.

111 ANY ve PCDATA 222 En basit eleman tanımı ANY buyruğu ile yapılır.

<!ELEMENTkutuphaneANY>

’ANY’ sözcüğü ile <kutuphane> ve </kutuphane> imleri arasında herhangi bir karakterin veya karakter katarının veya başka imlerin bulunabilmesi sağlanır. Eğer iki im arasında sadece özel bir takım karakterlerin tanımlanması isteniyorsa ’PCDATA’ anahtar sözcüğü kullanılır.

<!ELEMENTkutuphane(#PCDATA)>

Bu buyruk ile <kutuphane> ve </kutuphane> imleri arasında eleman isimleri hariç diğer karakterlerin yer alabileceği belirtilir. Bir örnek vermek gerekirse

<kutuphane>KTU Kütüphanesi</kutuphane>
<kutuphane></kutuphane>

kullanımları doğru olduğu halde

<kutuphane>
<universite>KTU</universite>
Kütüuphanesi
</kutuphane>

kullanımı yanlıştır.

Bununla beraber bir elemanın içerisinde başka elemanların bulunma zorunlulu ğu şu şekilde belirtilir.

<!ELEMENT Insan (Baslik>>
<!ELEMENT Baslik (#PCDATA>>
Yukarıdaki örnekte Insan imi içerisinde Baslik imi bulunmak zorundadır.
15
<!ELEMENT Insan (Baslik, Tarih)>
<!ELEMENT Baslik (#Baslik)>
<!ELEMENT Tarih (#Tarih)>

Yukarıdaki örnekte ’Insan’ im’i içerisinde ’Baslik’ ve ’Tarih’ imleri olmak zorundadır ve belirtilen sıraya uymak zorundadır.

<!ELEMENT Insan (Baslik|Tarih)>
<!ELEMENT Baslik (#Baslik)>
<!ELEMENT Tarih (#Tarih)>

Yukarıdaki örnekte ’Insan’ im’i içerisinde ’Baslik’ veya ’Tarih’ imlerinden birisi olmak zorundadır. Ancak ikisi birden bulunamaz.

Gruplama ve Yineleme

Imlerin XML dökümanı içerisinde yer alma sırasını belirlemek mümkündür.

<!ELEMENT Insanlar ((baslik, yazar)| aciklama)>
<!ELEMENT baslik (#PCDATA)>
<!ELEMENT yazar (#PCDATA)>
<!ELEMENT aciklama (#PCDATA)>

Yukarıdaki örnekte ’Insanlar’ im’i içerisinde ya ’aciklama’ im’i olmak zorundadır ya da ’baslik’ ve ’yazar’ im’i ardarda olmak zorundadır. Ayrıca bu imlerin kaçar defa yer alabileceğini belirleyebilirsiniz.

? Ya bir kere, ya hiç
+ En az bir kere
* Bir çok kere veya hiç
<!ELEMENT yazar (yazarismi+)>
<!ELEMENT yazarismi (#PCDATA)>

Yukarıdaki örnekte ’yazar’ im’i içerisinde ’yazarismi’ im’i ya bir kere yer alacaktır veya hiç kullanmayacaktır. Buna benzer fakat daha karmaşık tanımlamalar yapmak mümkündür .

Boş İmler

XML dökümanı içerisinde yer alan boş elemalar ayrıca tanımlanmak zorundadır.

<!ELEMENT elemanismi EMPTY>
Entities

<I>General Entities</I>

Bir karakter kümesi için makro tanımlamak için kullanılır.

<!ENTITY isim "karsilik">

<, >, &, 've " karakterleri i»cin gereken tanımlamalarıkendi DTD dökümanınız içerisinde yapmak zorunda değilsiniz. Bunlar XML işlemcisi tarafından önceden yapılmıştır. Copyright sembolu için bir makro tanımı aşağıdaki gibi yapılabilir. Bu sembolün Unicode karşılığı 169 (Hexadecimal 0xA9) ’dur.

<!ENTITY copyright "&#xA9;">

<I>Parameter Entities</I>

Bir önceki gibi makrolar tanımlamak için kullanılır ancak tanımlanan makrolar sadece DTD içinde kullanılmak içindir. Bu şekilde tanımlanan bütün makro isimlerinin başına % sembolü konulur. Bu sembol makronun sadece DTD içerisinde kullanılabileceğini gösterir.

<!ENTITY % isim "karsilik">

<I>External Entities</I>

Dısarıdan yapılan linkler için kullanılır.

<!ENTITY alinti SYSTEM
"http://www.Dunya.com/stocks/quoates.xml">

Eğer ‘alinti’ adli makro, XML dökümanı içerisinde kullanılacak olursa, işaret edilen URL’den yani http://www.Dunya.com/stocks/quoates.xml adresinden içerik alınacak ve XML dökümanı içerisine gömülecektir.

Örnekler

Örnek 1

<?xml version="1.0" standalone="yes"?>

<!DOCTYPE Insan SYSTEM "file:///bilisim/duygu/doc/xml/prog01.dtd">

<Insan>Beginning XML</Insan>

<!ELEMENT Insan (#PCDATA)>

<?xml version="1.0"?>

<xsl:stylesheet version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">

<xsl:value-of select="."/>

</xsl:template>

</xsl:stylesheet>

Örnek 2

<?xml version="1.0" standalone="no"?>

<!DOCTYPE Insan SYSTEM "file:///bilisim/Duygu/doc/xml/prog02.dtd">

<Insan> Insan

<Baslik>Duygu Caglar XML</Baslik>

</Insan>

<!ELEMENT Insan (Baslik)>

<!ELEMENT Baslik (#PCDATA)>

<?xml version="1.0"?>

<xsl:stylesheet version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">

<xsl:value-of select="."/>

</xsl:template>

<xsl:template match="Baslik">

<xsl:value-of select="."/>

</xsl:template>

</xsl:stylesheet>

Örnek 3

<?xml version="1.0" standalone="no"?>

<!DOCTYPE Kisi SYSTEM "file:///bilisim/Duygu/doc/xml/prog03.dtd">

<Kisi> Duygu Caglar </Kisi>

<!ELEMENT Kisi (#PCDATA)>

<?xml version="1.0"?>

<xsl:stylesheet version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">

<HTML>

<xsl:value-of select="."/>

</HTML>

</xsl:template>

</xsl:stylesheet>

Örnek 4

<?xml version="1.0" standalone="no"?>

<!DOCTYPE Insan SYSTEM "file:///bilisim/Duygu/doc/xml/prog04.dtd">

<Insan>

<Baslik>System Duygu Caglar</Baslik>

</Insan>

<!ELEMENT Insan (Baslik, Konu)>

<!ELEMENT Baslik (#PCDATA)>

<!ELEMENT Konu (#PCDATA)>

<?xml version="1.0"?>

<xsl:stylesheet version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">

<HTML>

<xsl:value-of select="."/>

</HTML>

</xsl:template>

</xsl:stylesheet>

Örnek 5

<?xml version="1.0" standalone="no"?>

<!DOCTYPE Insan SYSTEM "file:///bilisim/Duygu/doc/xml/prog05.dtd">

<Insan>

<Baslik>Duygu Caglar</Baslik>

</Insan>

<?xml version="1.0"?>

<xsl:stylesheet version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

20

<xsl:template match="/">

<HTML>

<xsl:apply-templates/>

</HTML>

</xsl:template>

<xsl:template match="Baslik">

<HEAD>

<xsl:value-of select="."/>

</HEAD>

</xsl:template>

</xsl:stylesheet>

Örnek 6

<?xml version="1.0" standalone="no"?>

<!DOCTYPE Insan SYSTEM "file:///bilisim/Duygu/doc/xml/prog06.dtd">

<Insan>

<Baslik>System Duygu Caglar</Baslik>

<Konu>System Yonetici Nitelikleri</Konu>

</Insan>

<!ELEMENT Insan (Baslik, Konu)>

<!ELEMENT Baslik (#PCDATA)>

<!ELEMENT Konu (#PCDATA)>

<?xml version="1.0"?>

<xsl:stylesheet version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">

<HTML>

<xsl:apply-templates/>

</HTML>

</xsl:template>

21

<xsl:template match="Baslik">

<HEAD>

<xsl:value-of select="."/>

</HEAD>

</xsl:template>

<xsl:template match="Konu">

<P>

<xsl:value-of select="."/>

</P>

</xsl:template>

</xsl:stylesheet>

Pazartesi, Haziran 02, 2008

WPF - Text & Flow Document

Metinler hazırladığımız uygulamaların vazgeçilmezledir. Windows Presentation Foundation ile metin işlemlerini kullanırken bir çok özelliği kolaylıkla kullanmamıza olanak tanınmaktadır. WPF, metin görüntülenmesine olanak tanınan her yerde yazılarımızı görüntülememize olanak tanımaktadır. Basit metin formatlarından çok daha karışık formatlara ve istediğimiz biçimde stillendirdiğimiz metinlere kadar çok geniş bir yelpaze WPF ile sunulmaktadır. Metinleri kullanırken yalnızca yazılarla kalmayıp kullanıcı kontrollerini, grafiklerini de kullanabilmemiz mümkündür. Metin işlemlerinde en göze çarpan ve yapılması istenen bir diğer özellik ise tip kontrolleridir. WPF‘ te bu işlemler içinde Typography sınıfı kullanılmaktadır. Ayrıca oluşturduğumuz olan metinlerin uygulamamızda daha derli toplu görülebilmesi için Flow Document ( akan belgeler ) ve Fixed Document ( değişmez belgeler ) sınıfları kullanılmaktadır. Bu sınıfların kontrollerini kullandığımız zaman ise bizlere birçok kontrolü içinde barındıran kontrol sunulmaktadır. Biz bu makalemize süresinde yukarıda bahsettiğimiz bütün özellikleri incelemeye çalışacağız. İlk olarak incelemeye başlamadan önce Flow Document kullanılan birkaç uygulamadan örnek olacak.

Türkiye’ de ve bütün dünyada Windows Presentation Foundation tanıtımları yapılırken gösterilen ortak bir uygulama vardı. Demoda bir gazetenin internete başlanmadan videoları, resimleri ve içerikleri ile birlikte bilgisayarda kullanılmasına olanak tanıyan bir örnekti. Gösterilen demo New York Times Reader ‘dır. Uygulamada, yazılar belirli ölçülerde büyültülüp küçültülürken sayfalamalar ona göre otomatik olarak şekillendiriliyor, düzenli olarak güncelleme alabiliyor ve hem hızlı hem de görsel olarak son kullanıcının hoşuna gidecek animasyonlar sunuyordu. Kısacası geliştiriciler ve kullanıcılar bu uygulamayı fazlasıyla beğenmekteydi. Şimdi bu uygulama ve bu uygulama esas alınarak hazırlanan başka bir uygulamanın ekran görüntülerini aşağıda göreceksiniz. Bu uygulamaların ortak yanları;

Windows Presentation Foundation ile yapılmış olmaları,
Flow Document kontrolünün kullanılmış olması,
İçeriklerinin web servisler ile otomatik olarak çekiliyor olması,
Arama için gerekli olan sorgularında LinQ To SQL kullanmaları,
Sayfa geçişlerinde ve arama işlemleri sonuçlarında animasyon kullanılması,
biçiminde sıralayabilmemiz mümkündür.


New York Times Reader


MSDN Libary

Yukarıda ekran görüntülerini gördüğünüz uygulamaların en belirgin özellikleri içeriklerinden bulunan metinlerin uygulamanın boyutuna göre kendisini otomatik olarak şekillendirmesidir.

Artık temel olarak metin ve flow document ile neler yapabileceğimize göz attığımıza göre bizlerde bu tür uygulamalar geliştirmek istediğimizde kullanabileceğimiz metin özelliklerini incelemeye başlayabiliriz.

Yazı Tipi ve Metin Stilleri

Metin ile ilgili işlemler ile uğraştığımızda bir çok aşamayı başarılı bir biçimde yapabilmemiz gerekmektedir. Fakat WPF ile sağlanan kolaylıklar ve bünyesinde barındırdığı bir çok yazı tipi stilleri sayesinde daha kolaylıkla yapabilmemiz mümkündür. Metin uygulamalarında altı çizili olması, kalın olması, eğik olması, farklı yazı tiplerinin kullanılabilmesi, boyutlarının kolaylıkla değiştirilebilmesi ve işletim sistemlerinin temalarından doğan sorunların oluşmaması gibi bir çok faktörü düşünerek hareket ederiz. WPF ile ise bahsettiğimiz bir çok faktörü HTML ile kod yazarken yaşadığımız kolaylık ile uygulayabiliyoruz.

Yaygın Metin Özellikleri

WPF ile hazırlamış olduğumuz uygulamalarda metinleri belirlediğimiz zaman TextElement sınıfını çağırmamız gerekmektedir. TextElement sınıfına dahil edilmiş birçok özelliği kullanarak en yaygın olarak kullanılan metin işlemlerini yapabilmemiz mümkündür. Şimdi bu sınıfı buton kontrolünün içerisinde nasıl kullanabileceğimizi basit bir örnek ile inceleyelim.

XAML Kod
<Button TextElement.FontFamily="Parchment" TextElement.FontSize="80" Height="96" VerticalAlignment="Top">
    Turhal Temizer
</Button>
<Button FontFamily="Parchment" FontSize="80" Height="96" VerticalAlignment="Bottom">
    Duygu Çaglar
</Button>

XAML koddan dikkat edeceğiniz üzere TextElement sınıfı ile metin özelliklerine belirleyebilirken aynı zamanda direk yapmak istediğimiz metinsel değişikleri belirterek de yapabilmemiz mümkündür. İkisi arasında bir fark yoktur ve özellikler penceresinde yaptığımız işlemlerin sonucunun sorunsuz olduğunu görebiliriz.



Butonumuzun görüntüsünün nasıl gözüktüğüne görmek gerekirse,



iki butonda da belirttiğimiz yazı tipi ve boyutu sorunsuz bir biçimde uygulanmış olduğu görülür.
Text Element miraslaşarak oluşturulan özellikleri ve ne işe yaradıklarını aşağıdaki gibi listeleyebiliriz.



Özellik Kullanımı
FontFamily
Yazı biçimini belirler(Arial, Calibri, v.b.).
FontSize Yazıların boyutlarını belirler. (XAML‘ de kullanabileceğimiz boyut standartları: in, cm, px, pt ‘dir. Bu kısaltmalar ayrıntılı olarak inç, santimetre, piksel, nokta.) Eğer herhangi bir standart girilmezse varsayılan olarak piksel kabul edilir.
FontStretch Yazının gerginliğini belirler. Condensed, Normal ve Expanded değerlerini alır.
FontStyle Yazınını stilini belirler. Italic ve Normal değerlerini alır.
FontWeight Yazını genişliğini belirler. Normal, Bold ve Light değerlerini alır.
Foreground Yazının rengini belirler.

Daha öncede bahsettiğimiz gibi yukarıdaki özellikler kullanıcı kontrollerinde dahili olarak kullanılmaktadır ve TextElement sınıfının tekrardan çağırılmasına gerek yoktur.

Yazı ve Yazı Ailesi

Ortak kullanılan (FontFamily) yazı ailelerine ve tiplerine yer verilmiştir. Fakat FontFamily sınıfı kullanabileceklerimizden yalnızca biridir. WPF uygulamalarında sıklıkla kullanılan üç sınıfı ve kullanım biçimlerine ilişkin bilgiler aşağıdaki tablodadır.

Sınıf Kullanımı
FontFamily Yazı tiplerini isimleri ile temsil eder. Arial, Calibri, Times New Roman v.b. yazı tipleri kullanılabilmektedir.
GlypTypeface Diskimizdeki yazı tipini kullanır. C:\Windows\Fonts\timesbi.ttf gibi. Belirtilen yazı dosyasının içerisinden yazıya ilişkin stil, boyut ve diğer özellikleri bulunmaktadır. Yolunu verdiğimizde ise kalın, yassı ve stili Times New Roman dır.
Typeface FontFamily özelliklerini kullanır. GlypTypeface ile oluşturulan görüntülenmeler Typeface ile tekrardan görüntülenebilir.

Windows Presentation uygulamaları geliştirilirken sıklıkla kullanılan yazı ailesi FontFamily ‘dir. Diğer iki yazı ailesi ise genellikle tasarımcılar tarafından özelleştirilen yazı stillerinin kullanılması durumunda kullanılmaktadır. Fakat kullanım sıklığı ve kolaylığı göz önüne alındığında FontFamily ‘nin daha fazla kullanıldığı gözlenir.

Yazı Boyutu (FontSize)

Metin işlemlerinde kullanacak olduğumuz yazının boyutunu istediğimiz biçimde şekillendirmemize olanak tanır. Hangi değerler ile boyutlarını yaygın metin özellikleri başlığının altındaki tabloda incelemiştik. Şimdi bu değerleri nasıl kullanabileceğimize XAML kod ile göz atalım.

XAML kod
<StackPanel>
    <TextBlock FontSize="40 px" Text="30 piksel"/>
    <TextBlock FontSize="40 pt" Text="30 nokta"/>
    <TextBlock FontSize="1.3 cm" Text="1.3 santimetre"/>
    <TextBlock FontSize="0.4 in" Text="0.3 inç"/>
</StackPanel>



Gerginlik (Stretch)

Metin uygulamalarında yer alan yazıların ekrandaki gerginliklerini belirlenmesine yarar. Kullanılan değerler FontStretches sınıfından çekilir. Bu değerler: UltraCondensed, ExtraCondensed, Condensed, SemiCondensed, Normal, Medium, SemiExpanded, Expanded, ExtraExpanded ve UltraExpanded dir.

Sıklıkla kullanılan yazı stillerinde gerginlik değeri olarak normal kullanılmaktadır. Eğer ki diğer özellikler kullanılırsa yatay olarak harfler ve rakamlar birbirlerine çok yaklaşacak ve okuma güçlüğüne sebep olacaktır. Örnek olarak MS Office ‘de yer alan yazı tiplerinden Gill Sans MT‘ yi deneye bilirsiniz. Harflerin birbirine yakın olmasından dolayı okunma oldukça zordur.

Stil (Style)

FontStyle özelliği ile kullanılmaktadır. Kullanabileceğimiz değerleri: Normal, Italic ve Oblique ‘dir. Metinlerde farklı gösterilmesi düşünülen kelimelerde uygulanır. Arial yazı ailesi ile yazmış olduğumuz bir yazıya stilleri uyguladığımızda oluşan sonuç aşağıdaki gibidir.



Weight

FontWeight özelliği metin uygulamalarındaki yazılarımızın daha koyu bir biçimde görülmesini sağlar. FontWeight sınıfında birçok değer kullanılmaktadır. Bunlar: ExtraLight/UltraLight, Light, Normal/Regular, Medium, DemiBold / SemiBold, Bold, ExtraBold / UltraBold, Black / Heavy ve ExtraBlack / UltraHeavy dir.

TextElement sınıfında kullanılmakla birlikte paragraf veya blok yazı alanlarında da kullanılması mümkündür. Metin belgelerinde genellikle önem sarf eden veya başlık olacak olan yazılarda sıklıkla kullanılmaktadır.

Decoration (Süsleme)

Decoration özelliği yazıların altını veya üzerine düz bir çizgi çizmeye yaramaktadır. Genellikle TextBlock içerisinde kullanılmaktadır. Ayrıca TextDecorations ile düz siyah çizgi çizmenin dışında belirli ölçülerde özelleştirebildiğimiz düzlemlerde çizilebilmektedir. Örnek vermek gerekirse;

<TextBlock TextWrapping="Wrap" TextAlignment="Center" FontSize="18">
    <Span TextDecorations="Underline">Turhal Temizer, </Span>
    <Span TextDecorations="Baseline"> Duygu Çağlar, </Span>
    <Span TextDecorations="Strikethrough">Gövdesinde, </Span>
    <Span TextDecorations="Overline">Üzerinde, </Span>
    <Span TextDecorations="Underline, Baseline, Strikethrough, Overline">Hepsi</Span>
</TextBlock>
 

Şimdi ki örneğimizde ise standart siyah çizgini yerine mavi renkli kalın bir çizgiyi nasıl oluşturabileceğimize göz atacağız.

<TextBlock Margin="0,74,0,-74" FontSize="38" TextAlignment="Center">
    <Span>
        <Span.TextDecorations >
            <TextDecoration Location="Underline" PenOffset="4">
                <TextDecoration.Pen>
                    <Pen Brush="Blue" Thickness="1"/>
                </TextDecoration.Pen>
            </TextDecoration>
            <TextDecoration Location="Strikethrough">
                <TextDecoration.Pen>
                    <Pen Brush="LightGreen" Thickness="1"/>
                </TextDecoration.Pen>
            </TextDecoration>
        </Span.TextDecorations>
        Turhal Temizer
    </Span>
</TextBlock>



Windows Presentation Foundation da TextDecoration işlemlerini XAML kod yardımı ile ne kadar kolay yapabileceğimizi öğrenmiş olduk.

Text Wrapping & Hyphenation ( Metin aktarma ve Kesikli çizgi )

Son kullanıcılara sunulan uygulamalarda genellikle doldurmalı alanlar kullanıcılar tarafından uygulama alanının genişliğinden daha fazla yer kullanarak taşmasına sebep olmaktadır. Bu tür sorunları ortadan kaldırmak için kullanıcıya sunulan kontrolün genişliği tamamlandı ise bir alt satıra geçirilmesi için ufak ayarlamalar yapılırdı. WPF ‘de bu işlemleri iki biçimde yapabilmemiz mümkündür. Bunlardan birincisi TextWrapping ‘tir.

TextWrapping özelliği yazı yazdırılan satır dolmuş ise bir alt satıra geçmesine olanak tanımaktadır. Örnekler ile bu özelliği incelemek çok daha yararlı olacaktır.

TextWrapping özelliğini kullanmadan,

<TextBlock TextWrapping="NoWrap" Text="Turhal Temizer, Istatistik ve Bilgisayar Bilimleri, Karadeniz Teknik Universitesi"/>



TextWrapping özelliğini kullanarak,

<TextBlock TextWrapping="Wrap" Text="Turhal Temizer, Istatistik ve Bilgisayar Bilimleri, Karadeniz Teknik Universitesi"/>



TextWrapping özelliğinin üçüncü değeri ise WrapWithOverflow ‘dur. Bu değer daha çok geniş boyutlu uygulamalarda Wrap ‘a göre daha iyi performans vermektedir.

TextWrapping özelliği ile birlikte kullanabileceğimiz Hyphenation özelliği kelimeleri satıra sığabilecek kadar uzatır ve sığmayan kısmına kesikli çizgi “-” koyarak bir alt satırda kaldığı yerden devam etmektedir. Örnek olarak göstermek gerekirse,

<TextBlock TextWrapping="Wrap" IsHyphenationEnabled="True" Text="TextWrapping özelliği kullanabileceğimiz Hyphenation ..."/>



Text Alignment ( Metin Hizalaması )

Yazıların sağa sola, ortaya veya her iki yana yaslı olarak yazılmasına olanak tanınmaktadır. Bu işlemin gerçekleşebilmesi için TextAlignment özelliğine right, left, justify ve center özelliklerinden herhangi birinin girilmesi yeterlidir. Özelliğin uygulamalarını sıklıkla MS Office ‘te görebiliriz. İlk açılan belge sağa yaslı olarak yazmaya başlarken biz onu sayfanın istediğimiz yerinde başlamasına olanak sağlarız.

Metin ve Kullanıcı Arayüzü

WPF uygulamalarında tasarım mimarisi kullanıcı kontrollerinin kullanımı üzerine kurulmuştur. Hiyerarşinin gerçekleşmesinden kullanılan sınıflardan biri Glyph sınıfıdır. System.Windows.Forms.Design.Behavior isim alanından miraslaşarak oluşturulmuştur. Kullanılan kontrollerin form üzerinde gösterdiği özelliklere göre düzenlenmiştir. Hiyerarşinin en üst kademelerinden birinde yer alan Glyph sınıfı ile birlikte GlyphRunDrawing sınıfı kullanılmaktadır. System.Windows.Media isim alanından miraslaşmıştır. Kullanılan sınıfların modellenmesi ile metin işlemlerinde kullanabileceğimiz TextBlock ve FlowDocumentReader kullanıcı kontrolleri bizlere sunulmuştur. Şimdi sıklıkla kullanılan metin kontrollerini incelemeye çalışalım.

TextBlock

TextBlock kontrolü genellikle basit metinlerin görüntülenmesinde kullanılmaktadır. Birkaç kelimelik cümlelerin yazımında yazı stillerinin özelleştirilmesi gibi özellikleri kullanabilmemiz mümkündür. Basit olarak TextBlock kontrolünün nasıl kullanacağını gösterirsek,

<TextBlock Text="Turhal Temizer"/>

XAML kod bloğu biçimindedir. TextBlock kontrolünün form üzerinde nerede duracağı FrameworkElement yardımı ile belirtilebilmektedir. Ayrıca WPF formda Grid alanı yerine StackPanel kullanırsak ta kullanmış olduğumuz yazılar ve kontroller biz aksini belirtmediğimiz sürece alt alta dizilecektir.

TextBlock ‘ta çoklu satırda kullanılabilmektedir. Fakat kullanımı için doğru karakterleri kullanabilmesi gerekmektedir. .Net ‘te Environment.NewLine özellikleri yardımı ile kullanılması mümkündür. Karakterler kullanılarak hazırlanmış TextBlock kontrol örneği aşağıdadır.

<TextBlock Text="Turhal&#x0a; Temizer" />

&#x0a; kullanıldığı taktirde bitiminden sonraki kelimenin bir alt satırdan başlamasını sağlamaktadır.

TextBlock kontrolleri kullanılırken yazı ailesi ve stillerde kullanılabilmektedir. Ayrıca içerik olarak belirttiğimiz metinleri <TextBlock> tagları arasında kullanabilmemiz mümkündür.

<TextBlock>Turhal Temizer</TextBlock>

Metinlerde öncelikli olarak göstermemiz gereken kelimeleri kalın olarak göstermek isteyebiliriz. Bunun için yapmamız gereken HTML kodda olduğu gibi Bold tagını kullanmak olacaktır (HTML ‘de bold tagı strong biçiminde kullanılmaktadır).

<TextBlock><Bold>Turhal Temizer</Bold></TextBlock>



Metin modellerinde kullanabileceğimiz stilleri yukarıda ayrıntılı bir biçimde açıklamıştık. Bahsettiğimiz özelliklerin hepsi TextBlock modeli içerisinde kullanılabilmektedir.

Label ve AccessText

Label, etiket olarak göstermek istediğimiz metinlerde sıklıkla kullanılmaktadır. Özellikle Windows Form ‘larda kullanıcı tarafından değiştirilmesini istemediğimiz metinleri kullanırken en sık tercih edilen kontroldü. Aynı şekilde bu kontrol TextBlock ile birlikte WPF form uygulamalarında da yerini almıştır. Fakat en belirgin farkı istediğimiz bir harfi klavyeden alt karakterine bastığımızda altı çizili olarak gösterebilmemizdir. Bu kullanım şeklini Windows Form ile yapmak istediğimizde kullandığımız karakterlerin hepsini ekranda göstermektedir. Altı çizili olarak gösterebilmek için istediğimiz bir harfin önüne “-” karakterini koymamız yeterli olacaktır.

<Label FontSize="20" Content="D_uygu Çağlar Label"/>

Label gibi kullanacağımız bir diğer kontrolde AccessText ‘tir. Bu kontrolde label gibi çalışmakla birlikte ilk kullanışta göze çarpan ilk farkı WPF formun en köşe noktasından başlıyor oluşudur. Label kontrolü en köşe noktadan bir boşluk mesafede metinleri göstermektedir. Kullanımda olmasa da metinleri girerken XAML kod tarafında ufak bir değişiklik ile metinleri girmek gerekmektedir. Label kontrolünden metinleri Content özelliği ile girerken AccessText kontrolü ile Text özelliği ile girmemiz gerekmektedir.

<AccessText Text="T_urhal Temizer AccessText"/>

İki kontrolün klavyeden alt karakterine basılması sonucunda aldığı ekran görüntüsü aşağıdaki gibi olacaktır.



FlowDocument

Flow Document kontrolü WPF ile gelen en büyük yeniliklerden biridir. Biraz önce bahsettiğimiz metin girme kontrolleri temel olarak uzun olmayan metinlerin girilmesinde kullanılmaktadır. Fakat paragraflarca metinlerin uygulamamıza eklenmesini istediğimizde o kontroller yeteri verimi verememektedir. Bu durumda bizlerin yapması gereken satır sonlarına geldiğinde düzenli olarak bir alt satıra geç, kullanıcı yazıyı büyütmek ve küçültmek istediğinde olabilmesi için kontroller yaz ve bunun gibi daha birçok işlemi yapmamız gerekmekteydi. Bunun yerine FlowDocument kontrolü kullanarak daha uygulamanın temellerinden karşılaşacağımız bir çok sorunu halletmiş oluruz.

Ayrıca ufak bir noktaya değinmek gerekirse, WPF form ile hazırlanmış uygulamalarda içerikleri gösterirken verilerin XML ile birlikte XPS (XML Paper Specifition) belgelerden çekildiğinden de bahsedilmektedir. Peki bu XPS doküman nedir? Şubat ayı itibari ile değiştirilemez doküman kategorisinde PDF ‘in yerine standart olarak kabul edilmiş bir belge türüdür. Kabul esnasında PDF ‘in kabul oranına nazaran çok daha yüksek bir oranla kabul edilmiştir. Belgeleri göstermek için internet tarayıcıları kullanmakta ve kullanımında kullanıcılara sunduğu işlemleri Flow Document ile gerçekleştirmektedir. Ayrıca Windows Vista ile hazırlanan belgeler XPS ile ve bu işletim sisteminin çıkması ile yaygınlaşmıştır. Microsoft ürünü olmakla birlikte diğer yazılım ve bilişim firmalarının da istediği bir belge standardıdır. Yalnızca lisans alım aşamasında Microsoft ‘un diğer firmalardan daha aktif davranmasından ötürü kendi bünyesine dahil etmedir.

XPS kullanımı esnasında API olarak System.IO.Packaging dönüşümünü kullanmaktadır. Daha ayrıntılı bilgi edinmek için ise http://www.microsoft.com/xps adresinden yararlanabilirsiniz.

FlowDocument oluştururken nasıl bir yol izlememiz gerektiğini örnek üzerinden anlatacağız. Bu işlem için <FlowDocument> kontrolü ve her paragraf için <Paragraph> üyesini kullanmamız gerekecektir.

<FlowDocument>
    <Paragraph FontSize="22">Text ile FlowDocument</Paragraph>
    <Paragraph FontSize="30">Flow Document</Paragraph>
    <Paragraph>Flow Document kontolü WPF ile …. </Paragraph>
    <Paragraph>…</Paragraph>
    <Paragraph>..</Paragraph>
</FlowDocument>



Flow Document kontrolünü kullanarak aramadan, boyut arttırmaya kadar birçok işlemi bir arada yapmamıza olanak tanınmaktadır. Bu işlemler esnasında yazı stillerinden sağa ve sola dayalı olması yazılar büyüdüğünde formumuza göre otomatik olarak şekillendirilmesi gibi bir çok özelliği otomatik olarak yapmaktadır.



Flow Document ile kullanabileceğimiz blokları aşağıdaki gibi listeleye biliriz.

Blok Kullanımı
Paragraph XAML kod bloğundan FlowDocument kontrolüne metin eklememize olanak tanır. Eklemiş olduğumuz metinler basit metinler olmalıdır. Sınırsız sayıda kullanılabilir. Diğer bloklar ile iç içe kullanılabilmektedir.
Section Diğer bloklara çeşitli özellikler atanmasına yarar. Diğer bloklara belirginlik, arka plan, yazı rengi ve buna benzer özellikleri belirlenmesinde yarar. Taglar içerisinde yazı metin yazılamaz. Paragraph gibi metin bloklarını kapsayacak biçimde tanımlanabilir.
List Listeleme yapılması için sıralı numara, roma rakamı, kalın nokta gibi standart listeleme simgelerinin kullanılmasına olanak tanır.
Table Belgelerde tablo ile gösterime ihtiyaç duyulduğunda kullanılmaktadır.
BlockUIContainer FlowDocument içerisine son kullanıcılara hitaben resim, video, buton ve üç boyutlu nesneler eklenmesine olanak tanır.

FlowDocument içerisinde kullanılabilecek blokların hepsinin ortak biçimde kullanıldığı bir örnek hazırlayalım. Örneğimizde başlığın arka plan rengi, listeli metin, BlockUIContainer ve tablo bulunacaktır.



XAML kod
<Window x:Class="mak43.Window8"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Flow Document">
    <!--Kapsamlı örnek-->
    <FlowDocument>
        <Section LineHeight="2" Foreground="White" Background="Black">
            <Paragraph FontSize="22">Windows Presentation Foundation</Paragraph>
            <Paragraph FontSize="30">Kısa Açıklamalar</Paragraph>
        </Section>
    <Paragraph>WPF: Ön plana çıkan özellikleri</Paragraph>
        <List>
            <ListItem>
                <Paragraph>Uygulama ile uyumu</Paragraph>
            </ListItem>
            <ListItem>
                <Paragraph>Çözünürlüğe bağımlılığı</Paragraph>
            </ListItem>
            <ListItem>
                <Paragraph>Donanımlar ile uyumu</Paragraph>
            </ListItem>
            <ListItem>
                <Paragraph>Bildirimli programlama</Paragraph>
            </ListItem>
            <ListItem>
                <Paragraph>Özelleştirelebilir zengin kontroller</Paragraph>
            </ListItem>
        </List>
        <BlockUIContainer>
            <Viewbox>
                <StackPanel Orientation="Horizontal">
                    <Image Source="yapi.jpg" Margin="5"/>
                    <TextBlock VerticalAlignment="Center" Width="100" TextWrapping="Wrap">
                        .Net Framework 3.0 teknolojisinden bulunanlar.
                    </TextBlock>
                </StackPanel>
            </Viewbox>
        </BlockUIContainer>
        <Paragraph>
            .Net 3.0 yapısının tablo ile gösterimi
        </Paragraph>
        <Table CellSpacing="5" Padding="15" FontFamily="Segoe UI">
            <Table.Background>
                <LinearGradientBrush>
                    <GradientStop Color="Yellow" Offset="0"/>
                    <GradientStop Color="Orange" Offset="1"/>
                </LinearGradientBrush>
            </Table.Background>
            <!-- dört sütün oluşturuluyor: -->
            <Table.Columns>
            <TableColumn/>
            <TableColumn/>
            <TableColumn/>
            <TableColumn/>
            </Table.Columns>
            <!-- üç satır oluşturuluyor: -->
            <TableRowGroup>
                <TableRow>
                    <TableCell ColumnSpan= "4" TextAlignment="Center">
                        <Paragraph FontWeight="Bold">.NET Framework 3.0</Paragraph>
                    </TableCell>
                </TableRow>
                <TableRow>
                    <TableCell BorderBrush="Black" BorderThickness="2" Background="LightGray"
                        TextAlignment="Center" LineHeight="70">
                        <Paragraph FontWeight="Bold">WPF</Paragraph>
                    </TableCell>
                    <TableCell BorderBrush="Black" BorderThickness="2" Background="LightGray"
                        TextAlignment="Center">
                        <Paragraph FontWeight="Bold">WCF</Paragraph>
                    </TableCell>
                    <TableCell BorderBrush="Black" BorderThickness="2" Background="LightGray"
                        TextAlignment="Center">
                        <Paragraph FontWeight="Bold">WF</Paragraph>
                    </TableCell>
                    <TableCell BorderBrush="Black" BorderThickness="2" Background="LightGray"
                        TextAlignment="Center">
                        <Paragraph FontWeight="Bold">WCS</Paragraph>
                    </TableCell>
                </TableRow>
                <TableRow>
                    <TableCell BorderBrush="Black" BorderThickness="2" Background="LightGray"
                        TextAlignment="Center">
                        <Paragraph FontWeight="Bold">ADO.NET</Paragraph>
                    </TableCell>
                    <TableCell BorderBrush="Black" BorderThickness="2" Background="LightGray"
                        TextAlignment="Center">
                        <Paragraph FontWeight="Bold">ASP.NET
                        </Paragraph>
                    </TableCell>
                    <TableCell BorderBrush="Black" BorderThickness="2" Background="LightGray"
                        TextAlignment="Center">
                        <Paragraph FontWeight="Bold">Windows Forms</Paragraph>
                    </TableCell>
                    <TableCell BorderBrush="Black" BorderThickness="2" Background="LightGray"
                        TextAlignment="Center">
                        <Paragraph FontWeight="Bold">...</Paragraph>
                    </TableCell>
                </TableRow>
            </TableRowGroup>
        </Table>
    </FlowDocument>
</Window>

Oluşturmuş olduğumuz uygulamanın boyutlarını değiştirdiğimiz taktirde uygulamamızın içerisinde yer alan metinlerde otomatik olarak şekillenecektir.

Span

Yazı stillerinde anlatırken altı çizili, kalın, yassı yazıların nasıl oluşturulacağından ayrıntılı bir biçimde değinmiştik. FlowDocument ile bu özellikler kullanılmak istendiğinde nasıl bir kullanım izleneceğine değinmeye çalışalım. Yazı ile anlatırken TextBlock kontrolü içerisinde nasıl kullanılacağından değinmeye çalışmıştık. Şimdi ise Paragraph bloğu arasında kullanacağız.

XAML Kod
<FlowDocument>
    <Paragraph>
        <Bold>Kalın</Bold>
        <Italic>Yassı</Italic>
        <Underline>Altında</Underline>
        <Hyperlink>Link</Hyperlink>
        <Span BaselineAlignment="Superscript">SıuperScript</Span>
        <Span BaselineAlignment="Subscript">SubScript</Span>
        <Span>
            <Span.TextDecorations>
                <TextDecoration Location="Strikethrough"/>
            </Span.TextDecorations>
            Strikethrought
        </Span>
    </Paragraph>
    <Paragraph>
    a
    <Bold>b
        <Italic>c
            <Underline>d
                <Hyperlink>e</Hyperlink>
            f</Underline>
        g</Italic>
    h
    </Bold>
    i
    </Paragraph>
</FlowDocument>



Sabit Bloklar

FlowDocument içerisine yerleştirmiş olduğumuz resim, videoların blok içerisinden nerede duracağını belirlememize olanak tanırlar. Sayfanın boyutunun değişmesi sonucunda oluşan görüntü bozukluklarını ortadan amaçlar. Ufak bir örnek ile nasıl kullanıldığına göz atalım.

<FlowDocument>
    <Paragraph FontSize="22">Windows Client</Paragraph>
    <Paragraph FontSize="30">WPF 'in Form Dünyasındaki Yeri</Paragraph>
    <Paragraph>
        <Figure Width="130">
            <BlockUIContainer>
                <Image Source="Turhal11.jpg"/>
            </BlockUIContainer>
        </Figure>
        Windows Presentation Foundation …
    </Paragraph>
    <Paragraph>Windows Form …</Paragraph>
    <Paragraph>…</Paragraph>
    <Paragraph>…</Paragraph>
    <Paragraph>…</Paragraph>
    <Paragraph>
        Tabii bu yalnızca bir görüş. Bize doğrusunu zaman gösterecektir.
    </Paragraph>
    <Paragraph>
        <Bold>Turhal Temizer</Bold>
    </Paragraph>
</FlowDocument>



FlowDocument ‘e eklemiş olduğumuz resim varsayılan olarak formun ilk sütununun sağ köşesine eklenmiştir. Eğer biz resmin yerine değiştirmek istiyorsak yapmamız gereken VerticakAnchor ve HorizontalAnchor değerlerini belirlemek olacaktır. Örnekler ile sonuçlarına göz atalım.


HorizontalAnchor="ColumnLeft"


HorizontalAnchor="PageCenter"


HorizontalAnchor="PageRight" ve VerticalAnchor="PageTop"

FlowDocument Görüntüleme

FlowDocument ile açıklamaları anlatırken hazır kontrolün özelliklerini kısıtlayabileceğimizden de bahsetmiştik. Uygumalarımızın sağ alt köşesinde görüntüleme ile ilgili üç adet seçenek çıkmaktadır. Eğer geliştiriciler isterse bu üç kontrolden herhangi birini XAML kod bloğunda FlowDocument tagından önce yazarak varsayılan olarak uygulatabiliriz ve değiştirilmesini engelleyebiliriz.

Görüntüleme ile ilgili üç seçeneğin ne işe yaradığını aşağıdaki tabloda ayrıntılı bir biçimde öğrenebilirisiniz.

Görütüleme Görevi
FlowDocumentScrollViewer Belgelerin web sayfalarında veya MS Word ‘de olduğu gibi aşağı yukarı kaydırma çubuğu ile hareketlenebilmesini sağlar.
FlowDocumentPageViewer MS Word ‘de tam ekran belgeleri okurken gözlemlenen yapının aynısı çalıştırılır.
FlowDocumentReader Diğer iki görüntülemenin özelliklerinin birleşimi biçimindedir. Kullanıldığı taktirde diğerlerinden farklı olarak arama çubuğuda aktif olmaktadır.
Görüntülemeler sonucunda aşağıdaki gibi sonuç alırız.

<FlowDocumentScrollViewer>
    <FlowDocument>
        ………………………
    </FlowDocument>
</FlowDocumentScrollViewer>



<FlowDocumentPageViewer>
    <FlowDocument>
        ………………………
    </FlowDocument>
</FlowDocumentPageViewer>



<FlowDocumentReader>
    <FlowDocument>
        ………………………
    </FlowDocument>
</FlowDocumentReader>



Dipnot Ekleme

FlowDocument ile hazırlanmış uygulamalara göz attığımızda dipnot ekleme gibi seçeneklerin bulunduğunu gözlemleriz. WPF, FlowDocument kontrolünde kullanabilmemiz için dipnot ekleme ve önemlilik belirleme gibi kontrolleri bizlere sunmuştur. Özellikleri kullanabilmemiz için Annotation sınıfını kullanabilmemiz gerekmektedir. Bunun için ise System.Windows.Annotations isim alanının uygulaya eklenmesi gerekmektedir. Dipnot işlemleri esnasında aşağıdaki kontrolleri kullanabilmemiz mümkündür.

Komut Kullanımı
CreateTextStickyNoteCommand Eklenmesi durumunda seçili metnin üzerine gelindiğinde yazı olarak not eklenmesini sağlar.
CreateInkStickyNoteCommand Eklenmesi durumunda seçili metnin üzerine gelindiğinde çizerek not eklenmesini sağlar.
DeleteStickyNoteCommand Etiket olarak eklenen dipnotları silmeyi sağlar.
CreateHighlightCommand CreateHighlightCommand
ClearHighlightCommand Renklendirilmiş metnin temizlenmesini sağlar.

Yukarıdaki komutları kullanarak FlowDocument uygulamamızı özelleştirelim.

Uygulamamıza başlarken ilk yapacak olduğumuz işlem System.Windows.Annotations isim alanını eklemek olacaktır.



Daha sonrasında ise aşağıdaki XAML kodları ekliyoruz.

XAML kod
<Window x:Class="mak43.Window10"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:a="clr-namespace:System.Windows.Annotations;assembly=PresentationFramework"
    Title="Dipnot" Initialized="Window_Initialized" Closed="Window_Closed">
    <StackPanel>
        <StackPanel Orientation="Horizontal">
            <Label>Dipnot Kontrolleri</Label>
            <Button Command="a:AnnotationService.CreateTextStickyNoteCommand"
                CommandTarget="{Binding ElementName=reader}">Yazılı Not</Button>
            <Button Command="a:AnnotationService.CreateInkStickyNoteCommand"
                CommandTarget="{Binding ElementName=reader}">Çizimli Not</Button>
            <Button Command="a:AnnotationService.DeleteStickyNotesCommand"
                CommandTarget="{Binding ElementName=reader}">Not sil</Button>
            <Button Command="a:AnnotationService.CreateHighlightCommand"
                CommandTarget="{Binding ElementName=reader}" >Üstünü çiz</Button>
            <Button Command="a:AnnotationService.ClearHighlightsCommand"
                CommandTarget="{Binding ElementName=reader}">Üstünü temizle</Button>
        </StackPanel>
        <FlowDocumentReader x:Name="reader">
            <FlowDocument>
                <Paragraph FontSize="22">Windows Client</Paragraph>
                <Paragraph FontSize="30">WPF 'in Form Dünyasındaki Yeri</Paragraph>
                <Paragraph>
                    <Figure Width="130" HorizontalAnchor="PageRight" VerticalAnchor="PageTop">
                        <BlockUIContainer>
                            <Image Source="Turhal11.jpg"/>
                        </BlockUIContainer>
                    </Figure>
                    …
                </Paragraph>
                <Paragraph>…</Paragraph>
                <Paragraph>…</Paragraph>
                <Paragraph>…</Paragraph>
                <Paragraph>…</Paragraph>
                <Paragraph>…</Paragraph>
                <Paragraph>
                    <Bold>Turhal Temizer</Bold>
                </Paragraph>
            </FlowDocument>
        </FlowDocumentReader>
    </StackPanel>
</Window>

C# kod
using System;
using System.IO;
using System.Windows.Annotations;
using System.Windows.Annotations.Storage;
using System.Windows;

namespace mak43
{
    public partial class Window10 : Window
    {
        FileStream stream;
        public Window10()
        {
            InitializeComponent();
        }
   
        private void Window_Initialized(object sender, EventArgs e)
        {
            //dipnotlar yükleniyor ve aktif yapılıyor.
            AnnotationService service = AnnotationService.GetService(reader);
            if (service==null)
            {
                stream = new FileStream("yedek.xml", FileMode.OpenOrCreate);
                    service = new AnnotationService(reader);
                AnnotationStore store = new XmlStreamStore(stream);
                store.AutoFlush = true;
                service.Enable(store);
            }
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            //silinyor ve kaydediliyor.
            AnnotationService service = AnnotationService.GetService(reader);
            if (service!=null && service.IsEnabled)
            {
                service.Disable();
                stream.Close();
            }
        }
    }
}

Uygulamamızı derlediğimiz zaman sonuç ise aşağıdaki gibi olacaktır.



Sonuç oldukça başarılı. WPF ile FlowDocument ‘i kullanarak uygulama geliştirmenin ne kadar kolay yapıldığını gözlemlemiş olduk. Artık bizde birkaç haftalık çalışma ile kolayca bir New York Times Reader yapabiliriz.

Yazımızı sonuna gelmiş bulunuyor. Bu yazıda nelere değindiğimize kısaca açıklamak gerekirse, ilk olarak neden bu yazıyı yazacağımızı açıkladık, sonrasında yazı ve metin ile ilgili işlemleri ayrıntılı bir biçimde incelemeye çalıştık. Son olarak da FlowDocument kontrolünü inceleyerek WPF ile yapılmış Reader uygulamalarına benzer bir uygulama geliştirdik.

Eğer ki bizlerde kendimiz için Reader uygulaması geliştirmek istersek bunu nasıl yapabiliriz?” diye kafanıza soru takılabilir. Onu da kısaca açıklamak gerekirse, yukarıda değindiğimiz konular sizin bir Reader yapmanıza yetecek düzeydedir. Fakat verilerinizi elle değil de dinamik olarak dışarıdan alacağınız için bu yazıları ya XML ‘de tutmalı ya da veri tabanından çekmelisinizdir. Bu işlem için web servis oluşturmalı ve ulaştığınız içerikleri uygulamada kullandığınız kontrollere bind (bağlamak) etmeniz gerekecektir. Daha sonrasında ise gerçek bir Reader uygulamasına sahip olmuş olacaksınız.

Windows Presentation Foundation ile Data Binding işlemleri nasıl yapılıyor?” diye kafanızda bir soru var ise daha önce yayınlanmış olan makaleyi okuyabilirsiniz.

Umarım yararlı olmuştur.

Yazımızda değinmiş olduğumuz uygulamanın kaynak kodlarına linkten erişebilirsiniz.
turhal.temizer@csharpnedir.com