This article has been localized into Turkish by the community.
Kaynaklar
WPF çok kullanışlı bir konsept sunuyor: Bir veriyi bir kontrole özel, tüm pencereye özel veya tüm uygulamayı kapsayacak şekilde kaynak olarak tutma yeteneği. Veri, sıradan bir bilgiden, WPF control hiyerarşisine kadar istediğin herhangi bir şey olabilir. Bu sayede veriyi bir yerde tutup istediğin yerden kullanabilirsin, bu yüzden çok kullanışlıdır.
Bu konsept stiller ve şablonlar için çok defa kullanılmıştır, bunları eğitimin ilerleyen zamanlarında açıklayacağız, fakat bu bölümde örnekleyeceğimiz gibi birçok farklı şey için kullanabilirsiniz. Ufak bir örnekle açıklayalım:
<Window x:Class="WpfTutorialSamples.WPF_Application.ResourceSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="ResourceSample" Height="150" Width="350">
<Window.Resources>
<sys:String x:Key="strHelloWorld">Hello, world!</sys:String>
</Window.Resources>
<StackPanel Margin="10">
<TextBlock Text="{StaticResource strHelloWorld}" FontSize="56" />
<TextBlock>Just another "<TextBlock Text="{StaticResource strHelloWorld}" />" example, but with resources!</TextBlock>
</StackPanel>
</Window>
Tüm pencereye ait kaynak Window.Resources kısmında tanımlanıyor. x:Key özelliği ile bu kaynağa uygulamanın diğer noktalarından StaticResource direktifiyle erişebileceğiniz bir isim veriliyor. Bu örnekte ben sadece basit bir string değer sakladım ve daha sonra iki TextBlock kontrol içinde değişik şekillerde kullandım.
Statik Kaynaklar vs Dinamik Kaynaklar
Şimdiye kadarki örneklerde StaticResource direktifi ile kaynaklara eriştim. Bundan başka alternatif olarak DynamicResource direktifi de vardır.
Ana farkı şu, statik kaynak sadece XAML yüklendiğinde değeri kullanılıyor. Daha sonra bu kaynak değeri değişirse StaticResource direktifi ile kullandığınız yerlerde değişimi göremezsiniz.
Öte yandan bir DynamicResource ihtiyaç duyulduğu yerde işlenir ve sonra değeri değişince tekrar işlenir. Sabit bir değere bağlanmak ya da değeri izleyip her değiştiğinde size yeni değeri gönderen canlı bir fonksiyona bağlanmak gibidir - tam olarak böyle çalışmıyor ama size fikir vermek açısından böyle anlatılabilir. Dinamik kaynaklar, uygulamanın başlatılması sırasında Kod arka planından eklenirse tasarım zamanında mevcut olmayan kaynakları da kullanmanıza izin verir.
Başka kaynak tipleri
Basit bir string'i paylaşmak kolaydı, ama daha fazlasını yapabilirsiniz. Bir sonraki örnekte ayrıca bir string array ve arkaplan renklendirmekte kullanılacak bir gradient fırça bilgisi saklayacağım. Bu size kaynaklar ile neler yapılabileceğine dair oldukça iyi fikir verecektir:
<Window x:Class="WpfTutorialSamples.WPF_Application.ExtendedResourceSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="ExtendedResourceSample" Height="160" Width="300"
Background="{DynamicResource WindowBackgroundBrush}">
<Window.Resources>
<sys:String x:Key="ComboBoxTitle">Items:</sys:String>
<x:Array x:Key="ComboBoxItems" Type="sys:String">
<sys:String>Item #1</sys:String>
<sys:String>Item #2</sys:String>
<sys:String>Item #3</sys:String>
</x:Array>
<LinearGradientBrush x:Key="WindowBackgroundBrush">
<GradientStop Offset="0" Color="Silver"/>
<GradientStop Offset="1" Color="Gray"/>
</LinearGradientBrush>
</Window.Resources>
<StackPanel Margin="10">
<Label Content="{StaticResource ComboBoxTitle}" />
<ComboBox ItemsSource="{StaticResource ComboBoxItems}" />
</StackPanel>
</Window>
Bu sefer bir kaç kaynak tanımladık, böylece Window nesnemiz bir string, bir string array ve LinearGradientBrush kaynağına sahip. String kaynak değeri Label kontrolün yazısı olarak kullanılıyor, string array ComboBox kontrolün elemanları olarak kullanılıyor ve gradient fırça da bulunulan pencere arka plan boyası olarak kullanılıyor. Gördüğünüz gibi hemen her şey kaynak olarak saklanabilir.
Yerel ve uygulama geneli kaynaklar
Şimdiye kadar pencere geneli kaynaklar tanımladık, bunlara tüm pencere içinde erişebilirsiniz.
Sadece bir tek kontrol için tanımlanmış kaynağa ihtiyaç duyarsanız, bu kontrol içinde tanımlayarak sadece ona özel yerel bir kaynak olmasını sağlayabilirsiniz. Tamamen aynı şekilde yapılır, tek farkı kaynağı hangi kontrol içinde tanımladıysanız sadece orada erişebilirsiniz.
<StackPanel Margin="10">
<StackPanel.Resources>
<sys:String x:Key="ComboBoxTitle">Items:</sys:String>
</StackPanel.Resources>
<Label Content="{StaticResource ComboBoxTitle}" />
</StackPanel>
Bu kullanım şeklinde kaynağı StackPanel kaynağı olarak tanımladık ve sonra onun alt kontrolü olan Label kontrolünde kullandık. StackPanel içindeki diğer kontroller de bu kaynağa erişebilir. Ama bu StackPanel dışındaki kontroller bu kaynağa erişemeyecek tabi ki.
Eğer birden fazla pencereden kaynağa erişmek isterseniz bu da mümkün. App.xaml dosyası da pencere ya da herhangi bir WPF kontrol gibi kaynak tanımları içerebilir ve eğer kaynak App.xaml içinde tanımlanmışsa projedeki tüm pencereler ve kontrollerden kaynağa erişilebilir. İşlem olarak pencere için yaptığımız tanımlamanın aynı tekniği kullanarak yapılır:
<Application x:Class="WpfTutorialSamples.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
StartupUri="WPF application/ExtendedResourceSample.xaml">
<Application.Resources>
<sys:String x:Key="ComboBoxTitle">Items:</sys:String>
</Application.Resources>
</Application>
Kullanımı da aynıdır - WPF verilen kaynağı önce kontrolde , sonra pencerede , sonra App.xaml'de arayacaktır.
<Label Content="{StaticResource ComboBoxTitle}" />
Arkaplan kodunda kaynak kullanımı
Şimdiye kadar tüm kaynaklarımıza direk olarak XAML içinde bir markup direktifi ile kullandık. Bununla beraber tabi ki kaynağa arkaplan kodundan da erişebilirsiniz. Bu bazı durumlarda çok kullanışlı olur. Önceki örnekte kaynakları nasıl farklı yerlerde tanımlayabileceğimiz gördük, bu örnekte arkaplan kodundan 3 değişik kapsamda tanımlanmış 3 değişik kaynağa erişeceğiz :
App.xaml dosyası :
<Application x:Class="WpfTutorialSamples.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
StartupUri="WPF application/ResourcesFromCodeBehindSample.xaml">
<Application.Resources>
<sys:String x:Key="strApp">Hello, Application world!</sys:String>
</Application.Resources>
</Application>
Ana Pencere :
<Window x:Class="WpfTutorialSamples.WPF_Application.ResourcesFromCodeBehindSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="ResourcesFromCodeBehindSample" Height="175" Width="250">
<Window.Resources>
<sys:String x:Key="strWindow">Hello, Window world!</sys:String>
</Window.Resources>
<DockPanel Margin="10" Name="pnlMain">
<DockPanel.Resources>
<sys:String x:Key="strPanel">Hello, Panel world!</sys:String>
</DockPanel.Resources>
<WrapPanel DockPanel.Dock="Top" HorizontalAlignment="Center" Margin="10">
<Button Name="btnClickMe" Click="btnClickMe_Click">Click me!</Button>
</WrapPanel>
<ListBox Name="lbResult" />
</DockPanel>
</Window>
Arkaplan kodu :
using System;
using System.Windows;
namespace WpfTutorialSamples.WPF_Application
{
public partial class ResourcesFromCodeBehindSample : Window
{
public ResourcesFromCodeBehindSample()
{
InitializeComponent();
}
private void btnClickMe_Click(object sender, RoutedEventArgs e)
{
lbResult.Items.Add(pnlMain.FindResource("strPanel").ToString());
lbResult.Items.Add(this.FindResource("strWindow").ToString());
lbResult.Items.Add(Application.Current.FindResource("strApp").ToString());
}
}
}
Gördüğümüz gibi üç farklı "Hello, world!" mesajı sakladık: Biri App.xaml içinde, biri window nesnesi içinde ve biri de yerel olarak pnlMain paneli içinde. Arabirim bir Button ve bir ListBox'tan oluşuyor.
Arkaplan kodunda butonun click olayını işliyoruz, içinde her bir string'i ekran görüntüsünde olduğu gibi ListBox'a ekliyoruz. Bunu yaparken kaynağı bulup (eğer bulursa) bize bir nesne olarak dönen FindResource() metodunu kullanıyoruz. Sonra bunu ToString() metodu ile tekrar string'e çeviriyoruz.
Dikkat ederseniz FindResource() metdounu farklı kapsamlar için kullandık - ilki panelde, sonra pencerede ve sonra da içinde bulunduğumuz Application nesnesinde. Kaynağı nerede arayacağımızı belirtmek mantıklı görünüyor ama hatırlarsak WPF'de kaynak yerelde olmazsa bir üst yapıda aranıyordu, yani prensip olarak FindResource() metodunu sadece panele de uygulasak, bulamadığı kaynakları bir üstte arayarak tüm kaynakları bulacaktı.
Aynısı diğerleri için geçerli değil ama - arama işlemi yapıda aşağı doğru olamaz, yani bir kontrolde tanımlanmış bir kaynağı aramaya application seviyesinden başlatamazsınız.