Makale Özeti

XAML diline detaylı bir giriş yazısı niteliğindeki bu yazı ile WPF ile uygulama geliştirirken kullanacağımız XAML dilini öğrenmiş oluyoruz.

Makale

XAML Nedir?

XAML (Zammel diye okunur) .Net Framework 3.0 programlama modelinde basitçe arayüzler tasarlama görevini üstlenmiş deklaratif bir işaretleme dilidir. Adını eXtensible MArkup Language kelimelerinin baş harflerinden alan XAML, gücünü ise XML'den almaktadır.

XAML ile WPF teknolojilerinden hem masaüstü uygulamaları hem de Web uygulamaları için arayüz tasarımı yapılabilir, zaten XAML'de tam olarak bu konu üzerine odaklanmıştır.

Bu teknoloji Web uygulamalarına aşina olanlara çok yabancı gelmeyecek bir teknoloji denilebilir. Web ortamında başka bir işaretleme dili olan HTML görsel arayüzü belirler iken, WPF uygulamalarında XAML bu görevi üstlenmiştir. Ancak HTML ile benzerliği benzer bir iş yapmaları ve etiketler aracılığı ile bu işi yapmaları ile sınırlıdır. Zira XAML'in arkasında .Net Framework sınıf kütüphanesi bulunmaktadır, bu da XAML'i çok güçlü kılmaktadır.

XAML ile hem masaüstü hem web uygulamalarının aynı arayüz kodu ile geliştirilebileceğini söylemiştik. Bunu biraz daha açacak olursak, masaüstü için tasarladığınız bir uygulamada kullandığınız düğmeyi, herhangi bir değişiklik yapmadan aynı kodlarda web uygulamalarında da görüntületebilirsiniz. Bu açıdan bakıldığında XAML, yıllardır yapılmak istenipte yapılamayan Masaüstü-Web programcılığının kaldırılması için büyük bir adım atmış oldu.

XAML size arayüzde bulunan nesneleri, bu nesnelerin başka nesneler ile olan ilişkilerini ve şekil, konum, renk, vs gibi tüm özelliklerini belirleme şansını verir. Ancak yine burada HTML ile ayırmak gerekirkse, XAML'in direk işaretlenmiş dillerden farkı, yazılan her etiketin aslında arka tarafta bir .Net sınıfı ya da yapısını temsil etmesidir ve ikisi arasında doğrudan bir bağlantı olmasıdır.

Tüm XAML dökümanları .xaml uzantısını alırken, XAML dökümanına ait kaynak kodu dosyaları ise (örn C# için) .xaml.cs uzantısını alır.

XAML Yazım Kuralları

XAML kodları yazarken dikkat edilmesi gereken en önemli kural, bilinen XML kurallarına uymaktır. Yani,

  • açılan etiketler kapatılmalıdır,
  • gereken şemalar verilmelidir,
  • büyük-küçük harf ayrımına uyulmalıdır,
  • hiyerarşi korunmalıdır,
  • mutlaka bir tane kök düğüm bulunmalıdır

Bu kurallar dışında, yukarıda da bahsedildiği gibi XAML'de bulunan her etiket CLR de bir nesneye karşılık gelmektedir. Dolayısı ile XAML kodları yazılırken, bu nesneye ait özellikler ve olaylar kodlanır. Bu yüzden de nesnelerin sahip olduğu özellikler ve olaylar doğru şekilde bildirilmelidir.

<kok_eleman>
<nesne ozellik="deger" ozellik2="deger2">
<alt_nesne ozellik="deger">
<alt_nesne.ozellik2>
<sinif ozellik="deger" />
</alt_nesne.ozellik2>
</alt_nesne>
<alt_nesne ozellik="deger" />
</nesne>
</kok_eleman>

Yukarıda standart bir XAML yazımı görünmektedir. Bu yazımda bir kök eleman, bu kök elemanın altında bir nesne ve özellikleri bulunmaktadır. Nesnenin altında iki tane alt nesne bulunmakta ve farklı şekilde özellikleri atanmaktadır. Sonrada açılan etiketler kapatılmaktadır. Bu yazım kurallarına uygun olarak yazılabilecek bir kod aşağıdaki gibidir.

<StackPanel>
<Button Content="Ben Bir Düğmeyim" />
</StackPanel>

XamlPad

XamlPad .Net Framework 3.0 SDK paketi ile beraber gelen ve sadece XAML kodlarının çıktılarını göstermeye yarayan bir bir editor olarak nitelendirilebilir. Özellikle Orcas sürümünü henüz edinemeyen kullanıcılar için işe yarayacağını düşünüyorum.

XamlPad sadece XAML ile yazılan kodların sonuçlarını göstermek ile mükellef bir uygulamadır, kaynak kodu dosyaları ya da C# gibi programatik kodlara destek vermemektedir.

Aşağıda XamlPad ile yazılan basit bir kod görünmektedir.

XamlPad sadece Page türündeki pencerelerin sonuçlarını kendi ekranında gösterebilir. Eğer Window türünde bir kod yazıldı ise bunun için F5 basılıp kodun çalıştırılması gerekmektedir.

XAML Objeleri

Daha önceden de bahsedildiği gibi XAML ile oluşturulan her nesne arka planda .Net sınıf kütüphaneleri içerisinde yer alan bir sınıfı (class) veya yapıyı (struct) temsil etmektedir. Ayrıca eleman üzerinde tanımlanacak her türlü özellik ve olay da, o sınıf ve yapının sahip olduğu özellik ve olayı temsil etmektedir.

XAML'in sahip olduğu bu özellik ile yazılıp kaydedilen her XAML dosyası çalıştırılırken, XAML Loader (yükleyici), belgede ismi geçen her türlü sınıfın bir örneğini oluşturacaktır. Bunu yaparkende sınıfların sahip olması gereken default constructor'ı (varsayılan yapıcıyı) çağırarak yapacaktır. Ayrıca XAML de kullanılabilecek sınıfların hepsinin public erişim belirteci ile belirlenmiş olması gerekmektedir.

Örneğin aşağıdaki kod tekrar ele alınacak olursa.

<StackPanel>
<Button Content="Ben Bir Düğmeyim" />
</StackPanel>

Bu kodda StackPanel ve Button isimli iki nesne tanımlanıyor. Bu nesneler WPF kütüphanelerinde aynı isimde bulunan sınıflar. Content özelliği (öznitelik veya attribute olarakda geçebilir) ise Button sınıfındaki bir nesnenin içerik olarak taşıdığı objeyi temsil eder. Dolayısı ile böyle bir kod aslında C# ile aşağıdaki gibi ifade edilir.

StackPanel stackPanel = new StackPanel();
Button dugme = new Button();
dugme.Content = "Ben Bir Düğmeyim";
stackPanel.Children.Add(dugme);

Nesne Özelliklerini Atamak

XAML dilinde nesnelere ait özelliklerine atayabilmek için o nesnenin örneğinin oluşturulabiliyor olması gerekir. Dolayısı ile kendisine ait bir default contructor'a sahip olması gerekmektedir. Şayet böyle bir yapıcıya sahipse nesnelere özellikler atanabilir.

Nesnelere özellik atama yöntemleri atanacak özelliğin karakteristiklerine göre çeşitlilik gösterebilir. Bu yüzden olayı basit atama ve kompleks atamalar diye ikiye ayırabiliriz.

Basit Atama (Öznitelik Sözdizimi)

Bu yöntemde özellik nesneye ait tanımlama kodu içerisinde atanır. Genelde basit, tek satırlı string ifadeler ve sayısal değerler için kullanılır. Yazması daha kolay bir yöntemdir, geçmişten beri işaretleme dili kullanan insanların en çok tercih ettiği yöntem olmuştur.

Aşağıdaki düğme örneğimizde Content özelliğine atanan değer bu şekilde atanmıştır.

<Button Content="Ben Bir Düğmeyim" />

Düğmeye bu şekilde birden fazla özellikte atanabilir.

<Button Content="Ben Bir düğmeyim" FontFamily="Trebushet MS" FontSize="15" Background="Beige" Foreground="Red" Width="150" Height="60"/>

Bu kod ile beraber, bej bir arka plan üzerine kırmızı olarak Trebushet MS fontunun 15 büyüklüğünde puntoları ile "Ben Bir düğmeyim" yazılmaktadır. Ayrıca düğmenin boyunun yüksekliğinin 60px, genişliğinin 150px olduğu belirlenmektedir.

Kompleks Atamalar

Kompleks atamalar, basit atama yöntemi ile atanamayacak olan özellikleri atamak için kullanılır. Çünkü her zaman atanmak istenen özellikler tek satır veya basit bir string ile ifade edilemeyebilirler. Bu durumda kompleks atama yöntemine başvurulabilir.

Bu yöntemde aşağıdaki gibi bir söz dizimi kullanılır.

<nesne ozellik1="değer1">
<nesne.kompleksozellik>
<deger ozellik="başka bir değer" />
<deger2 ozellik="başka bir değer" />
</nesne.kompleksozellik>
</nesne>

Bu atama yöntemini kendi düğme örneğimize uygulamak istersek aşağıdaki gibi olur.

<Button Content="Ben Bir düğmeyim" FontFamily="Trebushet MS" FontSize="15" Width="150" Height="60">
<Button.Background>
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<GradientStop Color="PowderBlue" Offset="0.4"/>
<GradientStop Color="Beige" Offset="0.6"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Button.Background>
<Button.Foreground>
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<GradientStop Color="Black" Offset="0.6"/>
<GradientStop Color="White" Offset="0.4"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Button.Foreground>
</Button>

Bu uzun kodun sonucunda aşağıdaki gibi bir görüntü oluşur.

Görüldüğü gibi son derece değişik bir düğme görüntüsü ortaya çıktı. Burada düğmenin üzerinde Gradient yöntemi ile efekt uygulanmış durumda. Düğmenin sol üstünden başlayan PowderBlue rengi ile sağ altından başlayan Bej rengi ortada buluşmakta, bununla beraber yazı rengide uygun olarak dönmektedir. İşte burada bu ayarları tek bir satır ile ifade edebilmek mümkün olmadığı için kompleks atamalar kullanılmaktadır.

Sitiller

Çoğu zaman nesnelere ait görsel özellikler tek tek nesneler bazında tanımlanmak yerine CSS mantığında olduğu gibi bir kaynakta (Resources) tanımlanır ve nesnenin bu tanımlamaları kullanması istenir.

Eğer tanımlanacak sitiller o pencere için geçerli olacaksa <Windows.Resources> etiketleri arasına yazılabilir. Şayet tüm uygulama için geçerli olacaksa <Application.Resources> etiketleri arasına yazılabilir.

<Window.Resources>
<Style x:Key="Dugmeler" TargetType="Button">
<Setter Property="Background" Value="Beige" />
<Setter Property="Foreground" Value="Red" />
<Setter Property="Width" Value="150" />
<Setter Property="Height" Value="60" />
</Style>
</Window.Resources>

Örneğin burada pencere içerisinde etkili bir sitil tanımlanmış durumda. Bu sitile de isim olarak Dugmeler ismi verilmiş. Bu sitilin etki edeceği nesne türü (TargetType) olarak ise Button türü verilmiştir. Ardından Setter etiketleri ile Property olarak hangi özelliğe değer atanacağı, Value ile de değerin ne olacağı belirlenmiştir.

Tanımlanan bu sitili kullanmak için ise düğmede aşağıdaki gibi bir değişiklik yapılmıştır.

<Button Style="{StaticResource Dugmeler}" Content="Ben Bir düğmeyim" Height="60" />

Burada eklenen Style özelliği, StaticResource ifadesi ile Dugmeler sitiline bağlanmaktadır.

Kod Eklemek

Normal şartlarda XAML, kod ile tasarımı ayrı tutmak üzere tasarlanmıştır ve içinde C# kodları bulunması pek doğal değildir; ancak imkansız da değildir. Böyle birşey istenirse, XAML kodları içerisinde <x:Code> </x:Code> etiketleri içerisinde istenen kodlar yazılabilir. Ama bu yazım sırasında da XML kurallarına uyulur.

<Button Click="Tikla" Style="{StaticResource Dugmeler}" Content="Ben Bir düğmeyim" Height="60" />
<x:Code>
<![CDATA[
// Will be added to generated source file
public void Tikla(object sender, RoutedEventArgs e)
{
MessageBox.Show("Merhaba Dünya");
}
]]>
</x:Code>

Burada XML kurallarından kasıt <![CDATA[ ile başlaması ve ]]> ile bitmesidir. Burada kod olarak eklenen bir olay metodudu olduğu için bi metodu bir olaya atamak için düğmemizin Click olayına metodun adı yazılmıştır. Sonuçta aşağıdaki görüntü oluşmuştur.

Böylece bir yazımızın daha sonuna gelmiş olduk, bir sonraki makaleye kadar görüşmek üzere.