Silverlight ilk çıktığı günlerde en çok şaşırdığımız noktalar biri "Label"
adında bir kontrolün bulunmamasıydı. İşlevsellik olarak aynı çözümü sunan
TextBlock kontrolünü çok kısa bir sürede keşfetmiş olsak da
neden isminin değiştiğini pek anlayalamıştık. Bugünlerde
Silverlight
Toolkit paketi ile beraber özel bir Label kontrolü geldi.
Nedir TextBlock ile Label'ın farkı?
Aslında kaba tanımı ile TextBlock kontrolü Label'ın yapı
taşıdır. Bir Label kontrolü ControlTemplating desteklerken
TextBlock desteklemez. Zaten Label
Template'leri oluştururken biz de TextBlock'lardan faydalanacağız. Özetle
Label'lar gelişmiş TextBlock kontrolleridir de diyebiliriz. Sözü daha çok
uzatmadan gelin neler yapabildiğimize göz atalım.
Not: Silverlight Toolkit'i kullanabilmeniz için
CodePlex
üzerindeki adresten kütüphaneyi indirerek içerisindeki
Microsoft.Windows.Controls.dll dosyasını projenize referans
olarak eklemelisiniz.
Bir Label kontrolünü Silverlight Toolkit'in referans alınmış olduğu herhangi
bir projede rahatlıkla kullanabilirsiniz. Expression Blend içerisinde "Asset
Library" kısmında "Custom Controls" sekmesinde Label kontrolünü
bulabilirsiniz. TextBlock'larda da oluğu gibi herhangi bir Label
içerisine yazı yazmak için Content özelliğinden
faydalanabilirsiniz.
[XAML]
<UserControl x:Class="SilverlightApplication2.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300" xmlns:controls="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls">
<Grid x:Name="LayoutRoot" Background="White">
<controls:Label HorizontalAlignment="Left" VerticalAlignment="Top" Content="Deneme Amaçlı Metin"/>
</Grid>
</UserControl>
Basit bir şekilde Label kontrolünün kullanımına dair
yukarıdaki XAML kodunu inceleyebilirsiniz. Bir TextBlock ile Label kontrolünü
birbirinden ayıran özelliklerden ilki Label kontrolünün BorderBrush
alabiliyor olması. Hatta sadece bu kadarla kalmayıp bir Label'ın hangi
kenarlarında Border bulunacağına da karar verebiliyorsunuz.

Label kontrolünün BorderBrush ayarları.
Aynı şekilde isterseniz bir Label için Background da
belirleyebilirsiniz. Fakat makalemizin başından beridir bahsettiğimiz Label'ın
en önemli özelliği aslında ControlTemplating'e olanak tanıması. Gelin şimdi
Expression Blend içerisinde Label kontrolümüze sağ tıklayarak gelen menüden "Edit
Control Parts / Create Empty" komutunu verelim. Böylece hali hazırda sahnede
olan Label'ın görselliği yok varsayılarak bizim Label kontrolünün yapısını
tekrar tasarlayabilmemiz sağlanacak. Bunun için ilk aşamada karşınıza gelen
pencerede bu şablona bir de isim vermeniz gerek. Unutmayın hazırlanan şablonlar
sonrasında birden çok Label'a linklenerek merkezi bir yerden kullanılabilir.

Label kontrolü için yeni bir ControlTemplate yaratıyoruz.
ControlTemplate'imizi yarattıktan sonra Blend bizi otomatik olarak
Template tasarımına götürecektir. Bu sahnede otomatik olarak gelen Grid
nesnesini bir Canvas'a çevireceğiz. Bu seçimi tamamen örneğin
kolay ilerlemesi için yapıyoruz. Siz kendi tasarımlarınızda farklı Layout
kontrolleri tabi ki kullanabilirsiniz.

ControlTemplate tasarımımız bitmek üzere.
Tasarımımızda Canvas'ın içerisinde bir Rectangle koyarak
Fill özelliğine de Radial bir
GradientBrush atadık. Rectangle'ın önünde de bir TextBlock koyuyoruz.
Label içerisinde metni gösterecek olan bu TextBlock kontrolü
olacak. Label kontrolünün Content özelliğine verilen değerlerin
otomatik olarak şablon içerisinde bu TextBlock'un Content'ine
aktarılmasını sağlamalıyız. Bunu da ancak TemplateBinding ile
yapabiliriz.

Blend arayüzünden TemplateBinding ayarlarımızı yapıyoruz.
Blend'in arayüzünde şablonumuzu tasarlarken TextBlock
kontrolümüzü seçtikten sonra ekranın sağında kalan "Properties" sekmesinden söz
konusu TextBlock'un Content özelliğini ayarladığımız yerin
hemen yanındaki ufak kareye tıklıyoruz. Gelen menüden "Template Binding"
komutunu verdikten sonra Blend bize ana kontrolün hangi özelliğinin şablondaki
bahsi geçen özelliğe bağlanacağını soruyor. Tabi biz de hemen Content
özelliğini seçiyoruz. Böylece Label kontrolünün Content
özelliğini şablonun içindeki TextBlock'un Content
özelliğine bağlamış olduk.

Template tasarımı modundan çıkalım.
Artık tasarımımızı tamamladığımızda göre şablon tasarım modundan çıkıp ana
uygulamaya geri dönebiliriz. Artık Label kontrolünün Content'ini
değiştirdiğinizde ayarladığınız görsellik içindeki Textblock'a yerleştiğini
görebilirsiniz. En güzel de yeni bir Label eklediğinizde aynı şablonu
kullanmasını sağlayabilirsiniz.

Hazırladığımız şablonu istediğimiz Label kontrolünde kullanabiliriz.
Uygulamanıza yeni bir Label ekledikten sonra hazırladığınız şablonu bu Label
üzerinde de kullanmak istiyorsanız doğrudan söz konusu Label'a sağ tuş ile
tıklayarak gelen menünden "Edit Control Parts / Apply Resource"
diyerek şablonunuzu adı ile seçebilirsiniz. Böylece geri dönüp bu şablonda bir
değişiklik yaptığınızda birden çok Label'da değişiklik yapmış olacaksınız.
Merkezi yönetim :)
Yaptığımız tüm işlemlerin sonucunda aşağıdaki XAML kodu yaratılıyor.
[XAML]
<UserControl x:Class="SilverlightApplication2.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300" xmlns:controls="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls">
<UserControl.Resources>
<ControlTemplate
x:Key="DenemeSablon" TargetType="controls:Label">
<Canvas>
<Rectangle Height="50" Width="200" Stroke="#FF000000">
<Rectangle.Fill>
<RadialGradientBrush>
<GradientStop Color="#FF000000"/>
<GradientStop Color="#FFFFFFFF" Offset="1"/>
</RadialGradientBrush>
</Rectangle.Fill>
</Rectangle>
<TextBlock TextWrapping="Wrap" HorizontalAlignment="Stretch" Canvas.Top="17" Canvas.Left="45.348" Foreground="#FFFFFFFF" Text="{TemplateBinding
Content}"/>
</Canvas>
</ControlTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<controls:Label HorizontalAlignment="Left" VerticalAlignment="Top" BorderBrush="#FFFF0000" BorderThickness="10,0,5,0"
Template="{StaticResource
DenemeSablon}" Content="Tamamen Denemedir"/>
</Grid>
</UserControl>
Yukarıdaki kodda özellikle önemli olan birkaç nokta var. İlk olarak nasıl
olmuş da Label'ımız UserControl.Resources altındaki
DenemeSablon
adlı şablona bağlanmış? TemplateBinding'in kodu nasıl yazılmış?
Tüm bunların cevaplarını kod içerisinde kalın yazılı bölümlerde bulabilirsiniz.
Label'a DataBinding nasıl yapılır?
Bir Label'e neden DataBind yapmak isteyelim? Sonuçta sadece
Text göstermeyecek mi? Ve bu Text'in değişme şansı da yok ki
TwoWayBinding vs gereksin? Tüm bu soruların cevabı aslında
yukarıdaki ControlTemplating ile de alakalı. Bir Label
düşünün ki kendisine Bind edilmiş nesneye göre şekil alabiliyor? Ne dersiniz?
Bir önceki örneğimizden devam edelim. Varsayalım ki Label'ımızda bir ürünün
adını göstereceğiz fakat ürünün satış miktarına göre de Label'ın arkasında
Gradient'ın (Aslında Rectangle) şeffaflaşmasını veya görünür olmasını istiyoruz.
Bunun için ilk olarak gelin kontrolümüzün tasarımını biraz değiştirelim.

DataBind yapacağımız Label kontrolünün şablonunu biraz değiştirdik.
Sadece renklerde biraz değişiklik yaptık. Böylece arkadaki Rectangle tamamen
şeffaf olsa da yazı görünebilecek. Şimdi geçelim kod tarafına ve bu Label'a
nasıl veri bağlarız ona bakalım.
İlk olarak Label'a bağlayacağım Urun'ümüzün bir sınıf olarak programatik
anlamda tanımlamamız gerekiyor.
[VB]
Public Class Urun
Private PAdi As String
Public Property Adi() As String
Get
Return PAdi
End Get
Set(ByVal value As String)
PAdi = value
End Set
End Property
Private PSatis As Double
Public Property Satis() As Double
Get
Return PSatis
End Get
Set(ByVal value As Double)
PSatis = value
End Set
End Property
End Class
[C#]
public class Urun
{
public string Adi { get; set; }
public double Satis { get; set; }
}
Gördüğünüz üzere Urun sınıfımızın iki Property'si
var. Bunlardan ilki ürünün ismini saklayacak olan Adi, diğeri
ise Satis miktarı. Özellikle Satis
Property'sinin Double olarak tanımlandığına dikkat edelim.
Herhangi bir Convertor kullanmadan bu Property'si Bind
edeceğimiz için Opacity ile uyumlu şekilde 1 ile 0 arasında
Double değerler taşımalı.
[VB]
Private Sub Page_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
Etiket.DataContext = New Urun() With {.Adi = "Bir ürün adı", .Satis = 0.5}
End Sub
[C#]
private void Page_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
Etiket.DataContext = new Urun { Adi = "Bir ürün adı", Satis = 0.5 };
}
Kodumuzda basit bir şekilde yeni bir ürün yaratarak Etiket
adındaki Label kontrolümüze DataContext
özelliği üzerinden bağlıyoruz. Peki Adi ve Satis
Property'leri Label içerisinde neleri etkileyecek? İşte bunun
için ayrıca XAML tarafında ayarlar yapmamız gerek.

Rectangle'ın Opacity'sinin DataBinding ayarlarını yapıyoruz.
Blend tarafında Label kontrolünün şablonuna tekrar geri dönüyoruz. Daha önce
yarattığımız ControlTemplate'i açarak üzerinde değişiklikler yapmamız gerekiyor.
İlk olarak şablon içerisinde Rectangle'ı seçerek Properties
tabından Opacity'sinin yanında ufak kareye tıklıyoruz ve gelen menüden "Custom
Expression" komutunu seçiyoruz. Böylece artık binding ile ilgili ayarı
doğrudan el ile yazacağız.

DataBinding için Custom Expression yazıyoruz.
Yazdığımız Custom Expression ile artık Label kendi içindeki
Rectangle'ın Opacity değerinin kendisine verilen datadan
geleceğini ve bağlanması gereken Property'nin adının da Satis
olduğunu biliyoru. Aynı işlemi ControlTemplate içerisindeki
TextBlock için de yaparak bu sefer TextBlock'un Content
özelliğini Adi Property'sine {Binding Adi}
Custom Expression'ı ile bağlamamız gerek.
Tüm bu işlemleri yaptıktan sonra uygulamayı çalıştırdığınızda bağladığınız
verideki ürün adının TextBlock içerisine yerleştiğini ve gelen satış bilgisine
göre de arkadaki Rectangle'ın şeffaflığının belirlendiğini görebilirsiniz.
Böylece gelen veriye göre görselliğini değiştiren bir Label tasarlamış olduk.
Hepinize kolay gelsin.