WPF - Styles

Web programlama ile ilgilenenler CSS ‘in ne kadar yararlı olduÄŸunu bilirler. Bilmeyenler için ise kısa bir bilgilendirme yapalım. Web sayfamızda kullanacak olduÄŸumuz tasarımları, yazı fontlarını, renkleri ve daha birçok özelliÄŸi belirleyebildiÄŸimiz dosyalardı. Daha sonrasından ise belirlemiÅŸ olduÄŸumuz bu tasarımları gerekli yerlerde kullanarak hem zaman kaybından kurtulurken hem de web sayfamızda ekstra kod yazmaktan kurtuluyorduk.

Bu makalemizde Web uygulamalarından aşina olduğumuz stil işlemlerinin Windows Presentation Foundation ile nasıl yapabileceğimizi incelemeye çalışacağız.

Not: Visual Studio 2008 sp1 beta1 , .Net Framework 3.5 sp1 beta1 ve .Net Framework 3.0 sp2 beta1 12 Mayıs 2008 tarihinde bizlerin kullanımına sunulmuÅŸtur. Kullanmak isteyenler www.microsoft.com/download adresinden gerekli linki bularak indirebilirler. Fakat kurulması için sisteminizde kurulu olan beta ürünleri kaldırmanız gerekmektedir. Bu özellikle Silverlight 2,0 beta1 kullanan geliÅŸtiricileri ilgilendirmektedir. Beta ürünleri sildiÄŸimizde geliÅŸtirme yapıyorsak nasıl devam edeceÄŸiz derseniz ise SP1 beta1 ‘i kurduÄŸunuz zaman silmiÅŸ olduÄŸunuz yazılımlar geri yüklenecek ve diÄŸer yazılımlarınızda eksikleri giderilmiÅŸ olarak bizlere sunulacaktır.

Stil iÅŸlemlerini uygulama üzerinden anlatmaya çalışacağız. Uygulamamızı ise Visual Studio 2008 ürünü ile gerçekleÅŸtiriyor olacağız. VS2008 ‘i olmayan geliÅŸtiriciler ise isterlerse Expression Blend veya C# Express Edition ile de yapacak olduÄŸumuz uygulamaları yapabilmeleri mümkündür. BahsettiÄŸimiz herhangi bir ürün ile WPF application projesi oluÅŸturarak stil iÅŸlemlerini incelemeye baÅŸlayabiliriz.

Stil işlemlerini incelerken uygulayacak olduğumuz senaryoyu özetlemek gerekirse. Ekranımızı kullanabileceğimiz iki sütuna bölerek bu sütunlara listbox ve buton kontrollerini ekleyeceğiz. Bu kontrolleri ve değerlerini ilk olarak bu kontrollere dâhil stil işlemleri ile daha sonrada style sınıfını kullanarak kontrollerimizde nasıl kullanabileceğimizi inceleyeceğiz.

Uygulamamızda kullanacak olduğumuz çalışma alanını iki sütuna bölüyoruz. Daha sonrada Listbox ve üç tane buton ekliyoruz.

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <ListBox Width="200" Height="150" Grid.Column="0" VerticalAlignment="Top">
        <ListBoxItem>Deger 1</ListBoxItem>
        <ListBoxItem>Deger 2</ListBoxItem>
        <ListBoxItem>Deger 3</ListBoxItem>
        <ListBoxItem>Deger 4</ListBoxItem>
        <ListBoxItem>Deger 5</ListBoxItem>
    </ListBox>
    <StackPanel Grid.Column="1" Orientation="Vertical" VerticalAlignment="Top">
        <Button>Ekle</Button>
        <Button>Duzenle</Button>
        <Button>Sil</Button>
    </StackPanel>
</Grid>

Çalışacak olduğumuz alanının tasarımını belirledik. Şimdi ise eklemiş olduğumuz kontrollere en temel yöntemle tasarım ile ilgili özelliklerini aktarmaya başlayalım. Özelliklerimize ekranda nerede olacağına , köşe renklerine, arka plan renklerine ve yazı boyutlarını belirliyoruz. Ayrıca butonlara belirttiğimiz özelliklere ek olarak yazı stili de ekliyoruz. Sizler farklı yazı stilleri eklemek isterseniz XAML kod tarafında işlemlerinizi yapmak yerine form üzerindeki kontrollere ait özelliklerden font-family seçeneğinden bulabilirsiniz.

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <ListBox Width="200" Height="150" Grid.Column="0" VerticalAlignment="Top">
        <ListBoxItem Margin="0,2,0,3" Foreground="Red" FontSize="18">Deger 1</ListBoxItem>
        <ListBoxItem Margin="0,2,0,3" Foreground="Red" FontSize="18">Deger 2</ListBoxItem>
        <ListBoxItem Margin="0,2,0,3" Foreground="Red" FontSize="18">Deger 3</ListBoxItem>
        <ListBoxItem Margin="0,2,0,3" Foreground="Red" FontSize="18">Deger 4</ListBoxItem>
        <ListBoxItem Margin="0,2,0,3" Foreground="Red" FontSize="18">Deger 5</ListBoxItem>
    </ListBox>
    <StackPanel Grid.Column="1" Orientation="Vertical" VerticalAlignment="Top">
        <Button Foreground="DarkBlue" Background="LightSkyBlue"
                    FontSize="15" FontFamily="French Script MT">Ekle</Button>
        <Button Foreground="DarkBlue" Background="LightSkyBlue"
                    FontSize="15" FontFamily="French Script MT">Duzenle</Button>
        <Button Foreground="DarkBlue" Background="LightSkyBlue"
                    FontSize="15" FontFamily="French Script MT">Sil</Button>
    </StackPanel>
</Grid>

Yukarıdaki kullanım biçimini sıkça uygulamalarımızda kullanıyorduk. Bu kullanım biçimini web uygulamalarında CSS kullanmadığımız zamanlarda görünen sayfaya tasarım bilgilerinin yazılması gibi kabul edebiliriz. WPF uygulamalarında ise bizim çalışma alanımızın dışında kalan bölümler stil dosyalarını belirleyeceğimiz bölümler olarak kullanacağız.

Eğer ki Expression Blend(EB) ile tasarım yapıyorsanız şimdi bahsedeceğimiz yönteme hiçte yabancı olmadığınızı fark edeceksiniz. Çünkü EB ile hazırladığınız tasarımlarda arka planda oluşturulmak olan XAML kodlar ekstra kod fazlalığını minimuma indirerek oluşturmaktadır. Bu sebepten ötürüde stil, animasyon gibi işlemlere ait kodları tek tek kontrollere eklemek yerine stil işlemleri stil sınıfına animasyon işlemlerini de Triggers sınıfına ekleyerek kullanmamızı sağlamaktadır.

Bizim hazırlayacak olduğumuz işlemlerin EB ile nasıl yapıldığını anlattıktan sonra şimdi bizde style sınıfını kullanarak tasarım işlemlerimizi miraslanabilir duruma getirebiliriz.

Penceremize ait özellikleri özkaynaklarında (resource) belirterek tekrardan kullanılabilir olmasına olanak tanıyoruz.



<Window.Resources>
    <Style x:Key="lb1" TargetType="ListBoxItem">
        <Setter Property="Margin" Value="0,2,0,3" />
        <Setter Property="Foreground" Value="Red" />
        <Setter Property="FontSize" Value="18" />
    </Style>
</Window.Resources>

Biraz önce kontrol içerisine eklemiş olduğumuz özelliklerin hepsini özkaynak olarak belirttik. Şimdi ise belirtmiş olduğumuz bu özkaynakları şimdi nasıl kullanacağımıza değinelim.

<ListBoxItem Margin="0,2,0,3" Foreground="Red" FontSize="18">Deger 1</ListBoxItem>

ListBox ‘a ait özellikleri en basit anlamda bu biçimde tanımlarken ÅŸu anda Style sınıfını kullanarak x:Key olarak belirlediÄŸimiz attribute ‘e baÄŸlayacağız.

<ListBox Width="200" Height="150" Grid.Column="0" VerticalAlignment="Top">
    <ListBoxItem Style="{StaticResource lb1}">Deger 1</ListBoxItem>
    <ListBoxItem Style="{StaticResource lb1}">Deger 2</ListBoxItem>
    <ListBoxItem Style="{StaticResource lb1}">Deger 3</ListBoxItem>
    <ListBoxItem Style="{StaticResource lb1}">Deger 4</ListBoxItem>
    <ListBoxItem Style="{StaticResource lb1}">Deger 5</ListBoxItem>
</ListBox>

ListBox kontrolünde deÄŸerleri tanımlamış olduÄŸumuz ListBoxItem ‘ın özelliklerinde Style sınıfından tanımlanmış olan özelliÄŸine statik olarak deÄŸeri baÄŸlıyoruz.

Åžimdi ise butonumuza ait özellikleri özkaynak olarak ayarlayalım. Style sınıfını kullanım yöntemine dikkat ettiyseniz standart olarak kontrollerde kullandığımız tasarım bilgilerini Setter sınıfının içerisinde özelliÄŸini ve deÄŸerini belirleyerek kullanıyoruz. Setter ‘ın içerisinden tanımlamış olduÄŸumuz özelliklere iliÅŸkin deÄŸerler intellisence ile bize sunulmamaktadır. Bizler bu özelliklere iliÅŸkin deÄŸerleri normalde kontrolün içerisinde kullanmış olduÄŸumuz özelliklerden yararlanarak belirliyoruz.

Style kullanmadan önceki buton kontrolümüze ilişkin görüntü;

<Button Foreground="DarkBlue" Background="LightSkyBlue"
            FontSize="15" FontFamily="French Script MT">Ekle</Button>

Kullanmış olduğumuz style sınıfı;

<Style x:Key="ekleButon" TargetType="Button">
    <Setter Property="Foreground" Value="DarkBlue"/>
    <Setter Property="Background" Value="LightSkyBlue"/>
    <Setter Property="FontSize" Value="15"/>
    <Setter Property="FontFamily" Value="French Script MT"/>
</Style>
    <Style x:Key="duzenleButon" TargetType="Button">
    <Setter Property="Foreground" Value="DarkBlue"/>
    <Setter Property="Background" Value="LightSkyBlue"/>
    <Setter Property="FontSize" Value="15"/>
    <Setter Property="FontFamily" Value="French Script MT"/>
</Style>
<Style x:Key="silButon" TargetType="Button">
    <Setter Property="Foreground" Value="DarkBlue"/>
    <Setter Property="Background" Value="LightSkyBlue"/>
    <Setter Property="FontSize" Value="15"/>
    <Setter Property="FontFamily" Value="French Script MT"/>
</Style>

BelirmiÅŸ olduÄŸumuz stilleri biraz önce ListBox kontrolünden kullandığımız gibi baÄŸlamamız gerekecektir. Yukarıdaki stil dosyalarını kontrol ederken kafanıza ufak bir soru takılabilir. “Stillerde kullanılan bütün özellikler aynı olduÄŸundan tek bir stilin içerisinde kullanıla bilemiyormuydu ? “diyebilirsiniz. Tabii ki de benzerlik olduÄŸu durumlardan tek bir stil sınıfında toparlamak mümkün olacaktır. Fakat daha sonra yapacak olduÄŸumuz deÄŸiÅŸikliklerden ötürü üç buton içinde ayrı ayrı stil ayarladık.

Buton kontrollerimizde stilleri kullanma ÅŸeklimiz;

<StackPanel Grid.Column="1" Orientation="Vertical" VerticalAlignment="Top">
    <Button Style="{StaticResource ekleButon}">Ekle</Button>
    <Button Style="{StaticResource duzenleButon}">Duzenle</Button>
    <Button Style="{StaticResource silButon}">Sil</Button>
</StackPanel>

Temel olarak stillerimizi oluşturduk ve gerekli olan kontrollerimize bağlamalarını yaptık. Şimdi isterseniz ekran görüntüsünün nasıl gözüktüğüne göz atalım.



Stilleri daha önceden oluşturupta kontrollere bağladığımızda herhangi bir sorun oluşmadan kontrollerimizin gerekli stillerine kavuştuğunu görürüz. Ayrıca dikkatinizi çekmek istediğimiz bir nokta var. Uygulamamızda kullanacak olduğumuz stillere ilişkin özellikleri çalışma penceremizin özkaynaklarına eklemeden önce XAML kod tarafımızın çok karmaşık olduğunu görürüz. Stillere ilişkin bilgileri özkaynak sınıfının içerisine eklediğimizde ise hem XAML kod tarafında oluşan karmaşık görüntüyü ortadan kaldırdı hem de bizleri aynı özellikleri defalarca kez yazmaktan kurtardı.

Şimdi ise düzenle ve sil butonlarımıza ilişkin stil özelliklerinde ufak değişiklikler yapalım. Sil butonunun dikkat çekmesi için yazı renklerini rengini kırmızı, düzenle butonunki ise yeşil olarak belirleyelim.

<Style x:Key="duzenleButon" TargetType="Button">
    ***
    <Setter Property="Foreground" Value="DarkGreen"/>
    ***
</Style>
<Style x:Key="silButon" TargetType="Button">
    ***
    <Setter Property="Foreground" Value="Red"/>
    ***
</Style>

Butonlara ilişkin stil özelliklerinde bu ufak değişiklikleri yaptıktan sonra uygulamamızı tekrardan çalıştırdığımızda değişikliklerin uygulandığını göreceksiniz.

ListBox kontrollerinde kullandığımız bütün kontrollere aynı stil sınıfını bağlamıştık. Şimdi ise hepsi için ayrı ayrı stiller oluşturacağız. Ekleyecek olduğumuz stiller de ana özellikler aynı olmakta birlikte yalnızca yazıların renklerini değiştireceğiz.

<Style x:Key="lb1" TargetType="ListBoxItem">
    <Setter Property="Margin" Value="0,2,0,3" />
    <Setter Property="Foreground" Value="Red" />
    <Setter Property="FontSize" Value="18" />
</Style>
<Style x:Key="lb2" TargetType="ListBoxItem">
    <Setter Property="Margin" Value="0,2,0,3" />
    <Setter Property="Foreground" Value="Blue" />
    <Setter Property="FontSize" Value="18" />
</Style>
<Style x:Key="lb3" TargetType="ListBoxItem">
    <Setter Property="Margin" Value="0,2,0,3" />
    <Setter Property="Foreground" Value="Green" />
    <Setter Property="FontSize" Value="18" />
</Style>
<Style x:Key="lb4" TargetType="ListBoxItem">
    <Setter Property="Margin" Value="0,2,0,3" />
    <Setter Property="Foreground" Value="Yellow" />
    <Setter Property="FontSize" Value="18" />
</Style>
<Style x:Key="lb5" TargetType="ListBoxItem">
    <Setter Property="Margin" Value="0,2,0,3" />
    <Setter Property="Foreground" Value="Cyan" />
    <Setter Property="FontSize" Value="18" />
</Style>

Özelliklerini değişitirdiğimiz listbox stillerini tek tek kontrollerine bağlamamız gerekmektedir. Onu da aşağıdaki gibi yapıyoruz.

<ListBox Width="200" Height="150" Grid.Column="0" VerticalAlignment="Top">
    <ListBoxItem Style="{StaticResource lb1}">Deger 1</ListBoxItem>
    <ListBoxItem Style="{StaticResource lb2}">Deger 2</ListBoxItem>
    <ListBoxItem Style="{StaticResource lb3}">Deger 3</ListBoxItem>
    <ListBoxItem Style="{StaticResource lb4}">Deger 4</ListBoxItem>
    <ListBoxItem Style="{StaticResource lb5}">Deger 5</ListBoxItem>
</ListBox>



Stil iÅŸlemlerini yaparken kafamıza şöyle bir soru takılabilir. “Tek bir stil sınıfında tanımlamış olduÄŸumuz özellikleri diÄŸer stil sınıflarına özelliklerini miraslayamaz mıyız?”. Bu sorunu cevabı tabii ki de evet olacaktır. Çünkü dikkat sizlerde dikkat etmiÅŸsinizdir ki hem ListBox kontrolü için hem de Buton kontrolü için hazırmış olduÄŸumuz stillerde birbirlerini tekrarlayan özellikler oldukça fazladır. Bizlerde bu tür iÅŸlemleri uygulamalarımızda daha az kod yazabilmek için yaptığımızdan dolayı farklı çözüm yolları üretmemiz gerekecektir. Style sınıfının özelliklerini incelediÄŸimizde Baseon özelliÄŸi dikkatimizi çekmektedir. Bu özellik baÅŸka bir stil sınıfındaki özellikleri kullanıldığı sınıfa miraslayabilmeye olanak tanıyor. Miraslama iÅŸlemini ise hazırlamış olduÄŸumuz stilleri kontrollere baÄŸladığımız biçimde kullanacağız.



Stillerde yer alan benzer özellikleri sadece tek bir stil sınıfında kullanarak diğer stil sınıflarına miraslama yani bağlama yapacağız. Bu işlemleri aşağıdaki gibi yapabilmemiz mümkündür.

<Window.Resources>
    <Style x:Key="lb1" TargetType="ListBoxItem">
        <Setter Property="Margin" Value="0,2,0,3" />
        <Setter Property="Foreground" Value="Red" />
        <Setter Property="FontSize" Value="18" />
    </Style>
    <Style x:Key="lb2" TargetType="ListBoxItem" BasedOn="{StaticResource lb1}">
        <Setter Property="Foreground" Value="Blue" />
    </Style>
    <Style x:Key="lb3" TargetType="ListBoxItem" BasedOn="{StaticResource lb1}">
        <Setter Property="Foreground" Value="Green" />
    </Style>
    <Style x:Key="lb4" TargetType="ListBoxItem" BasedOn="{StaticResource lb1}">
        <Setter Property="Foreground" Value="Yellow" />
    </Style>
    <Style x:Key="lb5" TargetType="ListBoxItem" BasedOn="{StaticResource lb1}">
        <Setter Property="Foreground" Value="Cyan" />
    </Style>
    <Style x:Key="ekleButon" TargetType="Button">
        <Setter Property="Foreground" Value="DarkBlue"/>
        <Setter Property="Background" Value="LightSkyBlue"/>
        <Setter Property="FontSize" Value="15"/>
        <Setter Property="FontFamily" Value="French Script MT"/>
    </Style>
    <Style x:Key="duzenleButon" TargetType="Button" BasedOn="{StaticResource ekleButon}">
        <Setter Property="Foreground" Value="DarkGreen"/>
    </Style>
    <Style x:Key="silButon" TargetType="Button" BasedOn="{StaticResource ekleButon}">
        <Setter Property="Foreground" Value="Red"/>
    </Style>
</Window.Resources>

Değişikleri yaptıktan sonra kodlarımızın ne kadar azaldığına görüyoruz. Bu sayede hem çalışma alanımızın boyutu küçüldü hem de bizler tekrardan stilleri düzenlemek istediğimizde çok daha kolay bir biçimde bu işlemi yapabilir duruma geldik.

Yaptığımız değişiklikler sonucunda ekran görüntüsünde ise herhangi bir değişiklik olmamıştır.



Son olarak butonlara iki farklı renkten oluşan arka plan stili ayarlayacağız. Bunu yapabilmemiz için stil sınıfında Background özelliğinin alt özelliklerinden olan LinearGradientBrush yararlanacağız. Ayrıca bir buton üzerinden değişiklik yaptığımız diğer butonlar o butonun özelliklerine bağlı olduğu için değişiklikler otomatik olarak aktarılacaktır. Bu sebepten ötürü yalnızca ekleButon stili üzerinde değişiklik yapıyoruz.

<Style x:Key="ekleButon" TargetType="Button">
    <Setter Property="Foreground" Value="DarkBlue"/>
    <Setter Property="Background">
        <Setter.Value>
            <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                <GradientStop Offset="0" Color="CornflowerBlue"/>
                <GradientStop Offset="1" Color="Bisque"/>
            </LinearGradientBrush>
        </Setter.Value>
    </
Setter>
    <Setter Property="FontSize" Value="15"/>
    <Setter Property="FontFamily" Value="French Script MT"/>
</Style>

Yapmış olduğumuz değişiklik sonucunda ekran görüntümüz ise aşağıdaki gibi olmuştur.



Stil işlemleri ile birlikte tasarımlarımızı ekleyebileceğimiz iki yöntem daha bulunmaktadır. Kısaca bu iki yönteme değinmeye çalışalım. Bunlardan birincisi yazımızda da değinmiş olduğumuz window.resource çalışma alanımızın özkaynaklarıdır. Bu sınıf içerisinde style dahil olmak üzere birçok özelliği saklayabilmemiz mümkündür. En sık olarak kullanılan yöntemde yaptığımız tasarımları özkaynak olarak saklamaktır. Çünkü uygulama çalıştırıldığında bu sınıf içerisindeki değerler kullanılmak üzere belleğin bir köşesinde tutulduğundan ötürü animasyon ve tasarım işlemlerinin kullanılması esnasından bu iki işlemden kaynaklanan performans kaybını minimuma indirgeyecektir.

KullanabileceÄŸimiz bir diÄŸer yöntem ise ControlTemplate ‘dir. Kullanıcı arayüzünde sıklıkla kullanılacak olan kontrolleri stilleri ile birlikte tanımlamamıza olanak tanımaktadır. Ä°ÅŸlevi ise UserControllere oldukça fazla benzemektedir. Daha sonraki yazılarımızda ControlTemplate 'e iliÅŸkin özelliklere deÄŸinmeye çalışacağız.

Sonuç olarak yazdıklarımızı toparlamak gerekirse, stil işlemlerini neden kullanmamız gerektiğine değinerek yazımıza başlamıştık. Sonrasında en acemi yöntem ile kontrollerimize tasarımsal özellikler ekledik. Bu özellikleri eklediğimizde XAML kod tarafının ne kadar karmaşıklaştığını ve kullanacak olduğumuz kontrol sayısının 3 - 5 değil de 100-200 olduğu durumlarda içinden çıkılamayacak bir durum oluşacağını göz önüne alarak kullanmış olduğumuz tasarım özelliklerini stil sınıfının özelliklerine nasıl kullanacağımıza değindik. En son olarak stil sınıflarında benzer olarak kullanılan özelikleri yalnızca bir kez tanımlayarak diğer stil sınıflarına nasıl miraslayacağımız gördük.

Umarım yararlı olmuştur.

Yazımızda değinmiş olduğumuz uygulamanın kaynak kodlarına linkten erişebilirsiniz.

Yorum Gönder

0 Yorumlar

Ad Code

Responsive Advertisement