Makale Özeti

XAML ile arayüz geliştirirken en çok ihtiyacımız olacak ve en çok kullanacağımız kontroller olan yerleşim kontrollerinden StackPanel, DockPanel ve Grid kontrollerini mercek altına alıyoruz.

Makale

Merhabalar, bu makalemizde XAML dilini öğrenmeye devam edeceğiz.Bir önceki makalede XAML diline genel olarak bir giriş yapmıştık. Bu genel bilgilerden sonra XAML ile arayüz tasarlarken bize en çok lazım olacak yapılardan, yani yerleşim (layout) kontrollerinden bahsedeceğiz.

WPF teknolojisinin temel hedef noktası gelişmiş arayüzler olduğu düşünürlürse, bu arayüzleri tasarlamak için birçok kontrolü ve yapısının olduğu tahmin edilecektir. Bunlardan en önemlileri de yerleşim yani layout kontrolleridir.

WPF ile uygulama geliştirirken daha önceki windows ortamlarından farklı olarak kontroller öyle istenildiği gibi her yere tek başlarına konulamaz. Örneğin standart bir Windows Forms 2.0 uygulamasında, çoğu kontrolü boş bir formun istediğiniz yerine koyabilirsiniz.Oysa web uygulamalarında kontrolleri bu şekilde yerleştiremezsiniz. İstediğiniz dizilimi sağlayabilmeniz için tablo yapılarını, div katmanlarını veya sitil kodlarını kullanmanız gerekir. WPF uygulamalarında da web'in bu yapısına benzer bir durum vardır ve ondan daha katı kurallara sahiptir. Web'te sayfaya kontroller tablo ya da başka bir yardımcı element kullanılmadan yerleştirilebilse de WPF'te bu mümkün değildir.

Daha önceki bilgilerimizi hatırlayacak olursak WPF'te temel de çeşit pencere yapısı bulunuyor. Window ya da Page. Bu her iki pencere yapısı da doğrudan herhangi bir kontrol barındıramazlar ve mutlaka aşağıda anlatılacak olan yerleşim kontrollerinden birini temel alarak kontrol barındırabilirler.

StackPanel Kontrolü

En temel yerleşim kontrolü olan StackPanel size basit bir şekilde kontrol yerleşim sorununu çözebilmeniz için yardımcı olur. StackPanel kontrolü yapısı itibari ile kontrolleri ya yatay olarak ya da dikey olarak bir sıralama ile tutar. Böylece içine eklediğiniz kontroller ya yan yana dizilerler ya da alt alta dizilirler. Burada tercih size kalmıştır.

<StackPanel Name="stackPanel1">
<Button Height="23" Name="button1" Width="75">Button</Button>
<Label Height="23" Name="label1" Width="120">Label</Label>
<TextBox Height="21" Name="textBox1" Width="120" BorderThickness="2" />
<Button Height="23" Name="button2" Width="75">Button</Button>
<Label Height="23" Name="label2" Width="120">Label</Label>
<TextBox Height="21" Name="textBox2" Width="120" />
<Button Height="23" Name="button3" Width="75">Button</Button>
<Label Height="23" Name="label3" Width="120">Label</Label>
<TextBox Height="21" Name="textBox3" Width="120" />
</StackPanel>

Görüldüğü gibi StackPanel içerisindeki tüm kontroller dikey bir eksende alt alta dizilmektedirler. Eğer buradaki kontrollerin yatay olarak dizilmesi istenirse kodda aşağıdaki gibi bir değişiklik yapılmalıdır.

<StackPanel Name="stackPanel1" Orientation="Horizontal" >
<Button Height="23" Name="button1" Width="75">Button</Button>
<Label Height="23" Name="label1" Width="120">Label</Label>
<TextBox Height="21" Name="textBox1" Width="120" BorderThickness="2" />
<Button Height="23" Name="button2" Width="75">Button</Button>
<Label Height="23" Name="label2" Width="120">Label</Label>
<TextBox Height="21" Name="textBox2" Width="120" />
<Button Height="23" Name="button3" Width="75">Button</Button>
<Label Height="23" Name="label3" Width="120">Label</Label>
<TextBox Height="21" Name="textBox3" Width="120" />
</StackPanel>

İki örnektende görülebileceği gibi StackPanel, kendisine eklenen diğer kontrolleri yatay ya da dikey bir dizilimde sıralamaktadır. Burada sıralamanın yatay ya da dikey olmasını belirleyen Orientation özelliğidir.

StackPanel'de veriler dikey olarak sıralanırken ekranın ortasında sıralandığı görülmüştü. Oysa bu sıralamayı ekranın sağına ya da soluna çekmek mümkün. Aynı şey yatay sıralamada, ekranın ortasında kalan sıralama içinde mümkün. Buradaki kontrollerde ekranın üst tarafına ya da alt tarafına alınabilir.

<StackPanel Name="stackPanel1" VerticalAlignment="Top" HorizontalAlignment="Right" Orientation="Vertical" >
<Button Height="23" Name="button1" Width="75">Button</Button>
<Label Height="23" Name="label1" Width="120">Label</Label>
<TextBox Height="21" Name="textBox1" Width="120" BorderThickness="2" />
<Button Height="23" Name="button2" Width="75">Button</Button>
<Label Height="23" Name="label2" Width="120">Label</Label>
<TextBox Height="21" Name="textBox2" Width="120" />
<Button Height="23" Name="button3" Width="75">Button</Button>
<Label Height="23" Name="label3" Width="120">Label</Label>
<TextBox Height="21" Name="textBox3" Width="120" />
</StackPanel>

Margin Özelliği

Margin özelliği birçok kontrole uygulanabilen ve virgüllerle ayrılmış sayılardan oluşan bir özelliktir. Bu özellik sırası ile, "Soldan, Üstten, Sağdan, Alttan" olan uzaklığı belirlemektedir. Dolayısı ile StackPanel gibi sırası ile elemanlarını dizen bir kontrol içindeki elemanlara Margin özelliği verilirse aşağıdaki gibi bir görüntü oluşur.

<StackPanel Name="stackPanel1" VerticalAlignment="Top" HorizontalAlignment="Right" Orientation="Vertical" Height="215" Width="189">
<Button Height="23" Name="button1" Margin="5,10,50,0" Width="75">Button</Button>
<Label Height="25" Name="label1" Margin="0,10,100,0" Width="55">Label</Label>
<TextBox Height="21" Name="textBox1" Width="69"Margin="100,20,0,0" BorderThickness="2" />
<Button Height="23" Name="button2" Width="75">Button</Button>
<Label Height="23" Name="label2" Width="47">Label</Label>
<TextBox Height="21" Name="textBox2" Width="66" />
<Button Height="23" Name="button3" Width="75">Button</Button>
<Label Height="23" Name="label3" Width="56">Label</Label>
<TextBox Height="21" Name="textBox3" Width="85" />
</StackPanel>

DockPanel Kontrolü

DockPanel kontrolü içerisine konan kontrolleri belli bir noktaya tamamen yayar ve öyle saklar. Cümleler ile anlatması zor olan bu tanımı hemen basit bir örnek ile açıklamaya çalışayım.

<DockPanel>
<Button Content="Düğme" DockPanel.Dock="Top" />
<Button Background="Beige" Foreground="Black" Content="2.Düğme" />
</DockPanel>

Görüldüğü gibi DockPanel içerisine konan düğmelerden birisinin DockPanel.Dock özelliği "Top" olarak ayarlanmıştır. Bu düğme hemen formun tüm üst bölümünü kaplamış, diğer düğme ise herhangi bir özellik verilmemiş olmasına rağmen kalan alanı kaplamıştır.

İşte DockPanel'in çalışma mantığı temel olarak budur, yani içerisindeki kontrolleri belirlenen bir eksende mümkün olan tüm alana yayarlar. DockPanel'e biraz daha kontrol ekleyip tekrar bakalım.

<DockPanel>
<Button Content="Düğme" DockPanel.Dock="Top" />
<Button Background="Beige" Foreground="Black" Content="2.Düğme" DockPanel.Dock="Right" />
<Button Background="Red" Foreground="White" Content="3.Düğme" DockPanel.Dock="Left" />
<Button Background="Brown" Foreground="Beige" Content="4.Düğme" DockPanel.Dock="Bottom" />
<Button Background="Black" Foreground="White" Content="5.Düğme" />
</DockPanel>

DockPanel'e farklı renklerde 5 düğme eklenmiştir, bu durumda aşağıdaki görünüm oluşmaktadır.

Görüldüğü gibi ilk düğme üst tarafta duruyor, çünkü DockPanel.Dock özelliği "Top" olarak ayarlanmış. 3. Düğme solda, 2. düğme sağda ve 4. düğme altta duruyor. 5. Düğme de kalan tüm alanı dolduruyor. DockPanel kontrolünde, kontrollerin ekleniş sırası bile önemlidir. Örneğin aşağıdaki sıra eklenmiş olsalalar idi başka türlü görünecekti.

<DockPanel >
<Button Background="Beige" Foreground="Black" Content="2.Düğme" DockPanel.Dock="Right" />
<Button Background="Brown" Foreground="Beige" Content="4.Düğme" DockPanel.Dock="Bottom" />
<Button Content="Düğme" DockPanel.Dock="Top" />
<Button Background="Red" Foreground="White" Content="3.Düğme" DockPanel.Dock="Left" />
<Button Background="Black" Foreground="White" Content="5.Düğme" />
</DockPanel>

Görülebileceği üzere sadece düğmelerine DockPanel'e ekleniş sırası değiştirilmiş durumda ama görünüm oldukça değişmiş durumda. Yine de yeri hiç değişmeyen 5. düğme, çünkü DockPanel eklenen son kontrolün tüm boş alanı kaplaması yönünde bir ayara sahiptir. Bu yüzden eklenen son düğme tüm boşluğu almaktadır. Eğer DockPanel'in LastChildFill özelliği false yapılır ise o zaman 5. düğme de kendinden bir önceki kontrol ile aynı DockPanel.Dock özelliğine sahipmiş gibi davranacaktı.

Grid Kontrolü

Yerleşim kontrolleri ile çalışırken kendizi en rahat hissedeceğiniz kontrol Grid kontrolü olsa gerek; çünkü Grid içerisine kontroller istenilen şekilde konulabiliyor. Örneğin aşağıdaki örnekte birçok kontrol Gris içerisinde istenilen yere yerleştirilmiştir. Bu örnekteki Margin kodlarını incelemenizi tavsiye ediyorum.

<Grid>
<Button Height="23" HorizontalAlignment="Left" Margin="50,0,0,47" Name="button1" VerticalAlignment="Bottom" Width="75">Button</Button>
<Button Height="23" Margin="87,0,117,70" Name="button2" VerticalAlignment="Bottom">Button</Button>
<Button Height="23" Margin="118,0,85,93" Name="button3" VerticalAlignment="Bottom">Button</Button>
<Button HorizontalAlignment="Right" Margin="0,97,12,0" Name="button4" Width="75" Height="23" VerticalAlignment="Top">Button</Button>
<RadioButton Height="16" Margin="87,30,71,0" Name="radioButton1" VerticalAlignment="Top">RadioButton</RadioButton>
<RadioButton Height="16" Margin="32,88,126,0" Name="radioButton2" VerticalAlignment="Top">RadioButton</RadioButton>
<TextBox Height="21" Margin="118,0,40,22" Name="textBox1" VerticalAlignment="Bottom" />
</Grid>

Ekran görüntüsününden de görülebileceği gibi düğmeler, radio buttonlar ve textbox istenilen yere konulmuştur ve bunda herhangi bir zorlama yoktur. Bu esnekliği sağlayan ise Margin özelliğidir, örneğin ekran görüntüsünde görülen düğmenin solunda ve altında çizgiler görünmekte, işte Margin özelliği de bu çizgilerin uzunluğunu göstermektedir. Solundaki çiz 50, altındaki çizgi 47 px uzunluğundadır. Üstünde ve sağında çizgi olmadığı için Margin'de buralar 0 değerini almıştır, böylece Margin değeri "50,0,0,47" olarak oluşmuştur. Margin değerleri, kontrolün Grid kontrolünün kenarlarından olan uzaklığına göre belirlenir.

Grid Kontrolünde Satırları ve Sütunları Kullanmak

Grid kelimesinin ızgara anlamına geldiğini biliyorsunuzdur, biz de bu anlamından yola çıkarak ona gerçek biz ızgara özelliği katacağız. Az önce yaptığımız örnekte kontrolleri serbestçe yerleştirmiştik, oysa istenirse bunlara bir düzen verilebilir. HTML'deki tablo yapısına benzer olarak Grid kontrolüne de satırlar ve sutunlar eklenerek kontroller bunların içerisine konulabilir.

<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="68" />
<RowDefinition Height="66.257" />
<RowDefinition Height="66.489" />
<RowDefinition Height="66" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="92" />
<ColumnDefinition Width="94" />
<ColumnDefinition Width="92" />
</Grid.ColumnDefinitions>
</Grid>

Grid'lere satırlar <Grid.RowDefinitions> özelliği ile sütunlar ise <Grid.ColumnsDefinitions> özelliği ile eklenir. İstenen sayıda satır ve sutün eklenebilir; ayrıca her satırın yüksekliği ve sütunun genişliği belirlenebilir. Yukarıdaki tanımlama 4 satır X 3 sütunluk bir yapı oluşturacaktır.

Oluşturulan bu hücrelere eleman eklemek için ise eklenecek her kontrolün Grid.Column özelliği ile sütununu, Grid.Row özelliği ile satırını belirlemek gerekmektedir. Satırlar ve sütunlar bilgisayar dünyasındaki herşey gibi 0'dan başlanarak sayılır ve eğer indexi 0 olan bir yere eklenecek ise belirtilmeyebilir.

<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="68" />
<RowDefinition Height="66.257" />
<RowDefinition Height="66.489" />
<RowDefinition Height="66" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="92" />
<ColumnDefinition Width="94" />
<ColumnDefinition Width="92" />
</Grid.ColumnDefinitions>
<Button Grid.Row="1" Name="button1">1</Button>
<Button Grid.Row="1" Grid.Column="1" Name="button2">2</Button>
<Button Grid.Row="1" Grid.Column="2" Name="button3">3</Button>
<Button Grid.Row="2" Name="button4">4</Button>
<Button Grid.Row="2" Grid.Column="1" Name="button5">5</Button>
<Button Grid.Row="2" Grid.Column="2" Name="button6">6</Button>
<Button Grid.Row="3" Name="button7">7</Button>
<Button Grid.Row="3" Grid.Column="1" Name="button8">8</Button>
<Button Grid.Row="3" Grid.Column="2" Name="button9">9</Button>
</Grid>

Dikkat edilecek olursa birinci, dördünci ve yedinci düğmelerde Grid.Column özelliği bulunmuyor, çünkü onlar 0 indeksine sahip sütuna eklenecekler, dolayısı ile verilmeyebilir. Bu kod ile aşağıdaki gibi bir görüntü elde edilmiş olmalı.

Görüldüğü gibi 9 tane düğme de sıralı ve düzgün bir şekilde eklenmiştir, ancak en üstteki satır boştur. Çünkü buraya 3 sütunu da kaplayacak bir TextBlock kontrolü ekleyeceğiz. Herhangi bir kontrolün birden fazla sütunu ya da satırı kullanması isteniyorsa kontrole Grid.ColumnSpan veya Grid.RowSpan özellikleri ile kullanılmak istenen satır veya sütun kadar yer açılmalıdır.

<TextBlock Grid.ColumnSpan="3" Grid.Row="0" Text="Sayılar" FontFamily="Verdanda" FontSize="50" TextAlignment="Center" Margin="0,8,0,0" />

TextBlock kontrolü Label kontrolüne benzeyen bir kontroldür, Text özelliği bir metin tutarak onun gösterilmesini sağlar. Burada Grid.Row özelliği 0 yapılarak ilk satıra, Grid.ColumnSpan özelliği 3 yapılarak, üç sütunu birden kaplıyacak şekilde büyük bir fontla ve ortalanmış olarak; ayrıca Margin özelliği ile üstten 8 pixel aşağı kaydıralarak eklenmiştir.

Böylece bu yazımızın sonuna gelmiş oluyoruz. Bu yazımızda yerleşim kontrollerinden StackPanel, DockPanel ve Grid kontrolünü inceledik. Bir sonraki yazımızda Canvas, TabPanel, WrapPanel kontrollerini ele alacağız. O zamana kadar kendinize iyi bakın, görüşmek üzere...