|
WPF - Resource Dictionary |
|
Gönderiliyor lütfen bekleyin... |
|
|
ResourceDictionary; programımız içerisinde kullanabileceğimiz kaynak kütüphanesini tanımladığımız sınıftır. Dikkat etmişseniz programlarımızı tek dosya üzerinde uzunca tanımlayıp kullanabiliyorken bu kod karmaşasına ve hatanın nerede kaynaklandığını bulmamamıza - özellikle yoğun görsellik içeren programlarımızda - neden oluyor. Bu durumu yenmek için Windows Forms ile çalışıyor olsaydık User Control(Kullanıcı Konrolleri), vs.. sistemlerle bu karışklığın üstesinden gelebilirdik. WPF programımızda ise bu stilleme ve kod karmaşasından bir düzeyde de olsa kurtulmak için, ResourceDictionary sınıfının nimetlerinden yararlanıyoruz.
WPF içerisinde Stillerin kullanımı için ve bu makaleye başlamadan önce WPF - Styles Kullanımı adlı, Turhal
Temizer in yazmış olduğu makaleyi okumanızı rica ediyorum.
ResourceDictionary komutları aslında basit olarak bir Button ya da TextBox yaptığımızda onun stillemesi ya da bağlantılı olduğu stillemeler (örneğin: renk, pozisyon, kaplamalar, vs... ) için tekrar tekrar uğraşmaktansa, bir ResourceDictionary(Kaynak Sözlüğü) sınıfı oluşturarak tüm bu ince detayları tek bir .xaml dosyasında toplayabiliyoruz. Referans olarak verdiğimiz kaynak dosyamızdan stillemeleri kullanan programımıza yapmamız gereken tek nokta ise sade şekilde tasarlamak oluyor.
ResourceDictionary sınıfını incelemek gerekirse,
ResourceDictionary xmlns="" |
Dışarıdan bir XML şablonu çağıracaksak kullanıyoruz. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" gibi... |
ResourceDictionary Source=" |
Kullandığımız sözlük dosyasını bir xaml dosyasında göstermek istediğimiz zaman dosyanın yüklenmesi için kullandığımız özellik.
<ResourceDictionary Source="Dictionary2.xaml"/> |
ResourceDictionary.MergedDictionaries |
Birden fazla Sözlük dosyasını birleştirmek için kullandığımız sınıf. Bu sınıf ile ilgili örneği aşağıda bulabilirsiniz. |
ResourceDictionary.Source |
Bir sözlük dosyası kaynağı oluşturmak istediğimiz zaman kullandığımız sınıfımız. |
Şimdi bir örnek üzerinde basitten karmaşığa doğru kaynak sözlüğü kullanımını inceleyelim.
Basit bir kaynak sözlüğü...
Öncelikli olarak WPFResourceDic adında bir WPF uygulaması yaratalım ve bu uygulamamızın içerisinde bir tane TextBox ile Button koyup Button1_Click olayına TextBoxımızda yazılmış olan yazıyı bir MessageBox ile göstermesini isteyelim.
private void button1_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(textBox1.Text + ", klasik WPF
projesi...");
} |
Sonraki aşamada Solution Explorer'dan WPFResourceDic projemizin ismine sağ
tıklayarak Add -> New Item yolunu izleyelim. Karşımıza gelen ekrandan,
sol taraftaki menüden WPF'e tıkladığımızda Resource Dictionary'i seçip projemize
ekleyelim. Alternatif bir yol için se yine projemizin ismine sağ tıklayıp Add
-> Resource Dictionary'i seçersek de projemize kaynak sözlüğünü eklemiş
oluruz.
Bu aşamadan sonra Dictionary.xaml dosyamızı yaratmış olduk. Şimdi App.xaml dosyasına gidip projemize bu kaynak sözlüğü dosyamızı tanıtalım. Bunun için App.xaml dosyasını açıp <Application.Resources> kod bloğu arasına <ResourceDictionary Source="Dictionary1.xaml" /> kodumuzu yapıştıralım.
Eğer ki birden fazla sözlüğümüz olacaksa ResourceDictionary.MergedDictionaries (Birleştirilmiş Sözlükler) kod sistemini kullanıyoruz. Bu işlemimiz de yaptıktan sonra artık basit bir stilleme için hazırız demektir. Dictionary1.xaml dosyamıza girip içerisine aşağıdaki kodumuzu yapıştıralım ve klasik kırmızı renkte bir fırça oluşturalım.
<SolidColorBrush x:Key="KlasikBrush" Color="#FF0000"/> |
Sonrasında Window1.xaml ile ana penceremize gidip Buttonun Background özelliğine bu rengimizi yapıştıralım.
Background="{StaticResource KlasikBrush}" |
Buraya kadar olan kısım gayet basit ve kolay. Şimdi işimizi biraz zorlaştıralım. Bir kaynak sözlüğü dosyası içerisinde diğer kaynak sözlüğü dosyasına referans verelim ve stillendirmemizi ayarlayalım. Tabi şimdi buttonun bir özelliğini değiştirmiş olduk. Bu biraz çocuk oyununa benzediğinden işimizi bu aşamada da zorlaştırıp herhangi tipte bir butonu gördüğünde direk aktif olacak bir kod yazalım. Yani biz artık butonun burasını değiştir demektense porjemiz içerisinde tek tip bir buton kullanacaksak bunu kaynak sözlüklerimiz ile tanımlayıp butona hiç bir şey eklemeden bu stillemeye geçmesini sağlayalım.
Bunun için önce Window1.xaml içerisinde eklediğimiz Background özelliğini silelim. Hiç bir şekilde bu ana dosyamıza kaynak gösterimi yapmayacağız. Sonrasında "Kaynaklar" adında bir klasör oluşturalım ve içerisinde Dictionary1.xaml ve Dictionary2.xaml adında iki tane kaynak sözlüğü dosyası atalım.
Bu Kaynaklar/Dictionary1.xaml dosyasının içine girip Dictionary2.xaml dosyamızdan kaynak alacağını şu kod bloğu ile gösterelim.
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary2.xaml"/>
</ResourceDictionary.MergedDictionaries> |
Bu aşamadan Kaynaklar/Dictionary2.xaml dosyamızı açalım ve içerisine kullanacağımız renk ve stillemeleri yazalım. İsteyen arkadaşlar sıfırdan yazabilecekleri gibi ben önceden yazmış olduğum stillemeleri - aşağıda - kullanabilirler.
<LinearGradientBrush x:Key="NormalBackgroundBrush" StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0" Color="#999"/>
<GradientStop Offset="0.4" Color="#333"/>
<GradientStop Offset="0.4" Color="#000"/>
<GradientStop Offset="1.0" Color="#666"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="PressedBackgroundBrush" StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0" Color="#FED8AA"/>
<GradientStop Offset="0.4" Color="#FBB565"/>
<GradientStop Offset="0.4" Color="#FA9D34"/>
<GradientStop Offset="1.0" Color="#FDEEAA"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="HighlightBackgroundBrush" StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0" Color="#FFFEE3"/>
<GradientStop Offset="0.4" Color="#FFE797"/>
<GradientStop Offset="0.4" Color="#FFD750"/>
<GradientStop Offset="1.0" Color="#FFE796"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<SolidColorBrush x:Key="aNormalForegroundBrush" Color="#000000"/>
<SolidColorBrush x:Key="NormalForegroundBrush" Color="#FFFFFF"/>
<SolidColorBrush x:Key="NormalBorderBrush" Color="#8DB2E3"/>
<SolidColorBrush x:Key="PressedBorderBrush" Color="#ABA18C"/>
<SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888"/>
<SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#EEE"/>
<SolidColorBrush x:Key="DisabledBorderBrush" Color="#AAA"/>
|
Bundan sonra Kaynaklar/Dictionary1.xaml dosyasına girip hangi nesneye ne türden bir özellik vereceğimizin kararına varalım. Bu kısmı uygularken bizim nesnemizin öncelikle bir yansımasını (Reflection) alıp üzerinde değişiklikler yapıyoruz. Bunu almak için WPF - Style kullanımı makalesinde olduğu gibi aynı kod bloğunu alırken küçük bir yerini değiştiriyoruz.
<Style TargetType="Button" x:Key="GelButton" >
<Setter Property="Margin" Value="1,2,1,2"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Template">
<Setter.Value>
...
</Setter.Value>
</Setter>
</Style> |
Kod blogunda <Style TargetType="Button" kısmını <Style TargetType="{x:Type Button}" olarak değiştiriyoruz. Bu sayede programımıza eklediğimiz her Button nesnesi bu belirlediğimiz stillemeyi kullanacak. İstersek oraya TabControldan TextBoxa kadar WPF nesnelerini ekleyebiliriz. Makalemizde isteyen arkadaşlar yukarıdaki kod blogundan devam ederek özellik değiştirebilirler. Diğer arkadaşlar için Kaynaklar/Dictionary1.xaml dosyasında kullanacağımız diğer kodları veriyorum.
Önemli not 1: Trigger ne işe yarar? Neden kullandık?
Trigger bizim bulunan durumda hangi olayın aktif olduğunu kontrol etmemize yarar. Yani, butonun üzerine gelindi mi? Gelindi. Butonun üzerine tıklandı mı? Tıklandı. Şeklinde özetleyebilirim. Stillememiz içerisinde Button nesnesinin tıklanması, üzerine gelinmesi gibi duruımlarına ayrı stillemeler yapacağımızdan dolayı kullandık. MultiTrigger ise bize Trigger durumu ile birden çok olayı yakalamızı sağlayabilir. Trigger sayesinde olayları yakalayabildiğimiz gibi Nesnenin özelliklerine de ulaşabilir üzerinde değişiklik yapabiliriz.
Önemli not 2: ControlTemplate ifadesi görüyoruz ve yanında bir TargetType="{x:Type Button}" ifadesi de görüyoruz, bu şimdi ne demek oluyor? Şöyle ki, biz nesnemizin özelliklerini değiştirmek, gerekli özelliklerine erişmek, durumunu anlamak (tıklanmış mı, üzerine mi gelinmiş) için kontrol etmek istediğimiz nesnenin yine Style da yaptığımız gibi bir yansımasını alıyoruz. Burada benim verdiğim kod örneği, buttonun durumlarına göre (tıklanma, üzerine gelme, aktif olma) stillemesini, özelliklerine göre yapıyoruz.
<Style TargetType="{x:Type Button}">
<Setter Property="Foreground" Value="{StaticResource NormalForegroundBrush}"/>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="border" CornerRadius="3" BorderThickness="1" BorderBrush="{StaticResource NormalBorderBrush}" Background="{StaticResource NormalBackgroundBrush}">
<ContentPresenter Margin="3" HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Foreground" Value="{StaticResource aNormalForegroundBrush}"/>
<Setter Property="Background" TargetName="border" Value="{StaticResource PressedBackgroundBrush}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource PressedBorderBrush}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsPressed" Value="False"/>
<Condition Property="IsMouseOver" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Foreground" Value="{StaticResource aNormalForegroundBrush}"/>
<Setter Property="Background" TargetName="border" Value="{StaticResource HighlightBackgroundBrush}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource PressedBorderBrush}"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{StaticResource aNormalForegroundBrush}"/>
<Setter TargetName="border" Property="Background" Value="{StaticResource DisabledBackgroundBrush}" />
<Setter TargetName="border" Property="BorderBrush" Value="{StaticResource DisabledBorderBrush}" />
<Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
|
Bu kodları girdikten sonra tek bir ayar yapmamız kalıyor. Dictionary1.xaml yani ilk başta yaptığımız App.xaml dosyası tarafından bilinen kaynak dosyasına Kaynaklar/Dictionary.xaml dosyasından kaynak alacağını belirten kod. Bunu istersek es geçip direk App.xaml dosyasına da Kaynaklar/Dictionary1.xaml dosyasından esinlen diyebiliriz. Fakat onunla uğraşmaktansa biraz daha düzenli olup neyin nereden geldiğini bilelim değil mi? Aşağıdaki kodu Dictionary1.xaml dosyamızda bulunan eski stil kodumuzun yerine ekleyelim.
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Kaynaklar/Dictionary1.xaml"/>
</ResourceDictionary.MergedDictionaries> |
İşte bu kadar bütün bu işlemleri yaptıktan sonra ortaya ne çıktığına bir bakalım.
Not: Bu sırada Window1.xaml dosyamızda önceden Button içerisine yazdığımız Background="{StaticResource KlasikBrush}" kodunu sildiğimizden emin olalım. Silmedi iseniz zaten hata verecektir.
Makalemiz burada son bulmaktadır. Artık ne kadar güzel stillemeler çıkaracağınız size kalmış. Kullandığımız kaynak dosyayı indirmek için lütfen buraya tıklayınız.
Ali Hıdımoğlu
[email protected]
http://www.boodergi.com/blog/ali
Makale:
WPF - Resource Dictionary .NET 3.0 ve .NET 3.5 Özel Bölümü Ali Hıdımoğlu
|
|
|
-
-
Eklenen Son 10
-
Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
|
|