Silverlight 5 Beta Markup Extensions

0 dakikada yazıldı

7732 defa okundu

Düzenle

XAML tarafındaki binding mekanizmalarını biliyoruz. Örneğin herhangi bir property'yi XAML tarafında tanımlı bir nesnenin bir attribute'üne bağlamak için aşağıdaki gibi basit bir binding syntaxi kullanabiliriz.

        \<TextBox Text="{Binding Metin, Mode=TwoWay}" />

Peki ya bu yapıların yeterli gelmediği senaryolarda kendi yapılarımızı tanımlama şansımız var mı? İşte tam da bu noktada Markup Extensions Silverlight 5 Beta ile karşımıza çıkıyor. Çoğu zaman ViewModel'lerinizi daha temiz tutabilmek ve olabildiğince View(XAML) ile ViewModel'i birbirinden uzak tutabilmek adına kullanabileceğimiz Markup Extensions özelliği gelin beraber inceleyelim.

Kendi extensionlarımızı yaratsak?

Kendi markup extension'ınızı yaratmanızı gerektirecek birçok senaryo ve neden bulunabilir. Biz şimdilik ufak bir lokalizasyon örneği üzerinden ilerleyelim. Böylece yapının nasıl çalıştığını ve implementasyonu incelemiş oluruz. Sonrası artık sizin hayal gücünüze kalır ;)

Örneğimizde herhangi bir kontrole verilecek olan String değerin lokalize olmasını sağlayacağız. Bu işlem Silverlight içerisinde farklı binding yapıları ile yapılabilir fakat synaxti basitleştirmeyi düşünürsek aşağıdaki gibi birşey hayal edebiliriz.

        \<TextBox Text="{Lokalizasyon Anahtar=Metin, Varsayılan=Bulunamadı}" />

Hayat ne kadar güzel olurdu değil mi? XAML kodu ne kadar da temiz gözüküyor :) Metin adında bir anahtarımız olduğunu ve anahtara denk gelen metnin dil dosyalarından alınacak TextBox'ın Text değerine verilmesi gerektiğini belirtmek keşke bu kadar kolay olsa. Diğer yandan bir ikinci parametre olarak da Varsayılan değerimiz var. Eğer lokalizasyon dosyalarında Metin anahtarı bulunamazsa bu değer Textbox'a aktarılacak. Eh, gelin şimdi buna benzer birşey yapalım.

[VB]

Public Class Lokalizasyon\     Inherits Markup.MarkupExtension\ \     Public Property Anahtar As String\     Public Property Varsayilan As String\ \     Public Overrides Function ProvideValue(serviceProvider As System.IServiceProviderAs Object\         Dim Metin As String = MevcutDil.Bul(Anahtar)\         If String.IsNullOrEmpty(Metin) Then\             Return Varsayilan\         Else\             Return Metin\         End If\     End Function\ End Class

İlk olarak yukarıdaki kod içerisindeki renkli kısımlara bakalım. Apayrı bir kod dosyası yaratarak projemize ekledikten sonra yeni bir sınıf yaratıyoruz. Bu sınıfımızın MarkupExtensions'ın türüyor olması çok önemli. Böylece kendi Markup Extension'ımızı yazabileceğiz. Sonrasında hemen bu markupda kullanmak istediğimiz olası parametreleri belirtiyoruz. Bizim örneğimizde Anahtar ve Varsayilan adında iki tane parametre hayal etmiştik. Hemen onları birer String Property olarak tanımlıyoruz.

[VB]

Public Class Lokalizasyon\     Inherits Markup.MarkupExtension\ \     Public Property Anahtar As String\     Public Property Varsayilan As String\ \     Public Overrides Function ProvideValue(serviceProvider As System.IServiceProviderAs Object\         Dim Metin As String = MevcutDil.Bul(Anahtar)\         If String.IsNullOrEmpty(Metin) Then\             Return Varsayilan\         Else\             Return Metin\         End If\     End Function\ End Class

Gelelim can alıcı noktaya. Kendi markup extension'ımızı yaratabilmemiz için bu extension'ın yapacağı şeyi de belirtmemiz gerek. Esas işlevselliği kodlayacağımız yer ProvideValue metodu olacak. Bu metodun içerisinde sınıfımızı gelen parametrelere göre gerekli kodları yazarak geriye ne döndürmemiz gerektiğine karar verebiliyoruz. Hatırlarsanız biz bir anahtara göre lokalizasyon dosyalarından metin döndürecektik.

Bu noktada lokalizasyonu nasıl implemente ettiğiniz kısmına bulaşmayacağız çünkü amacımız tam olarak o kısmı incelemek değil. MevcutDil.Bul adında static/shared bir metoda anahtar göndererek o an kullanıcının kullandığı dile göre metni aldığımızı düşünelim. Sonraki adımda bu metnin boş olup olmadığını kontrol ediyoruz. Eğer metin boş ise yapmamız gereken bize verilen Varsayilan parametresini geri göndermek ki binding sonrasında o metin gözüksün.

Tüm bu kodlamayı bitirdikten sonra artık XAML tarafına geçebiliriz. İlk Markup Extension'ımızı yazmış olduk. Sıra geldi onu kullanmaya. Bunun için hemen bu sınıfı tanımladığımız assembly için bir XML namespace tanımlayalım.

[XAML]

\\     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"\     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"\     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"\     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"\     mc:Ignorable="d"\              xmlns:daron="clr-namespace:SilverlightApplication4"\     d:DesignHeight="300" d:DesignWidth="400"\>

Yukarıdaki gibi istediğiniz bir isimle XML namespaceinizi tanımladıktan sonra doğrudan bu namespace üzerinden markup extensionımızı binding syntaxlarında kullanabiliriz.

[XAML]

    \<Grid x:Name="LayoutRoot" Background="White">\         \<TextBox Text="{daron:Lokalizasyon Anahtar=Metin, Varsayilan=Bulunamadi}" />\     \Grid\>

Başta hayal ettiğimize çok yakın bir yazım şeklini yakalayabildik değil mi? İşte MarkUp Extension bu işe yarıyor. Esasında ViewModel'in içinde ayağı olacak bir işlemi dışarı çekerek XAML kodunu da daha temiz tutabiliyoruz. Makrup Extension yapıları ile "Şunu da ben bunla yaparım" :) dediğiniz şeyleri yorum olarak bekliyorum ;) Bakalım neler çıkacak.

Görüşmek üzere.