This article is currently in the process of being translated into Hungarian (~99% done).
Resources
WPF bevezetésével egy nagyon hasznos lehetőséghez jutottunk: Az adatokat erőforrásként kezelhetjük, lokálisan a vezérlő elemekhez, lokálisan az egész ablakhoz rendelve vagy globálisan az egész alkalmazásra. Adat lehet nagyjából minden amit akarunk, az aktuális információktól a WPF vezérlők alárendeltségi viszonyáig. Ez lehetővé teszi hogy adatokat helyezzünk el egy helyen, elérjük és alkalmazzuk más helyekről is. Ez nagyon hasznos lehetőség.
Ezt a lehetőséget széleskörűen alkalmazható a különféle stílusok és sablonok készítésénél, de természetesen ahogy azt az alábbi példán keresztül érzékelhetjük, sok más esetben is alkalmazhatjuk. Engedjék meg hogy ezt egy egyszerű példával érzékeltessük:
<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>
Az erőforrásokhoz kulcs van hozzárendelve, az x:Key attribútum megadásával, mely lehetővé teszi azt hogy az alkalmazás más részeiből hivatkozzunk rá a kulcs alkalmazásával, összekötve a StaticResource jelölés kiterjesztéssel. A példában eltárolunk egy egyszerű sztring elemet, amit később két különféle TextBlock vezérlővel használunk.
Statikus erőforrások vagy dinamikus erőforrások
A példa programkódban a StaticResource jelölés alkalmazásával statikusként jelöljük az erőforrást. Persze alternatívaként alkalmazhatjuk az erőforrás dinamikus megjelölését is a DynamicResource jelölés alkalmazásával.
A fő különbség az hogy a statikus erőforrásokat egyszer kell értelmezni, azon a ponton ahol az XAML beolvasásra kerül. Amennyiben később az erőforrás megváltozik, az nem észlelhető, ha a StaticResource jelölést alkalmazzuk.
A DynamicResource ezzel ellentétben értelmezve vannak minden esetben először amikor felhasználásra kerülnek és utána minden esetben amikor az erőforrás megváltozik. Gondoljunk erre mint egyik esetben statikus kapcsolatra egy értékkel, másik esetben pedig mint egy metódusra ami figyeli az erőforrás értékét és elküldi minden esetben az alkalmazásnak, ha az megváltozott. Ez nem pontos leírása a folyamat működésének, de közelítő útmutatást ad arra, hogy mikor mit kell alkalmazni. A dinamikus erőforrások alkalmazása lehetővé teszi hogy olyan erőforrást alkalmazzunk, ami esetleg nem is létezik a fejlesztés szakaszában, hanem a háttér programkódban adjuk meg az alkalmazás indításakor.
Egyéb erőforrás típusok
Egy egyszerű sztring elem megosztása könnyű, de ettől sokkal többre is van lehetőség. A következő példában eltárolunk egy komplett sztring tömböt, színárnyalat információval együtt amit háttérszínként alkalmazhatunk. Ez a példa jó alapot ad arra, hogy az olvasó érzékelje az erőforrások felhasználásában rejlő széleskörű lehetőségeket.
<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>
Ebben a példakódban többféle erőforrást adunk meg, az ablakunk tartalmaz egyszerű sztring elemet, , sztring tömböt és LinearGradientBrush erőforrást. A sztring a címke elemhez kell, a sztring tömb elemeit a ComboBox vezérlőhöz alkalmazzuk, a LinearGradientBrush pedig az ablak háttérszínhez szolgál erőforrásként. Ezen a példán érzékelhető, hogy az nagyon sok minden megadható mint erőforrás.
Erőforrások helyi szinten és az applikáció szintjén
Eddig az erőforrásokat az alkalmazás ablak szintjén tároltuk, ami azt jelenti, hogy elérhető bárhonnan az applikáció ablak keretein belül.
Ha csak arra van szükség, hogy helyi vezérlőhöz rendeljünk egy erőforrást, amit máshol nem alkalmazunk, lehetőség van arra, hogy az erőforrást a helyi vezérlőhöz rendeljük ahelyett hogy az applikáció fő ablakhoz rendeljük. Ezt pontosan ugyanúgy tehetjük meg mint az előző esetben, a különbség abban áll, hogy az erőforrást csak a vezérlő hatáskörén belül érhetjük el, ahova definiáltuk. A kód a következő:
<StackPanel Margin="10">
<StackPanel.Resources>
<sys:String x:Key="ComboBoxTitle">Items:</sys:String>
</StackPanel.Resources>
<Label Content="{StaticResource ComboBoxTitle}" />
</StackPanel>
Ebben az esetben az erőforrást a StackPanel-hez rendeltük hozzá, és az annak alárendelt vezérlőben, címkében alkalmazzuk. Más alárendelt vezérlők a StackPanel-en belül szintén használhatják az erőforrást, valamint az adott vezérlőkből származtatott egyéb vezérlők is elérik. A StackPanel-en kívülről az erőforrás nem elérhető.
Ha arra van szükségünk, hogy az erőforrást több ablakból is elérjük, ez is lehetséges. Az App.xaml file tartalmaz erőforrásokat, ugyanúgy mint bármely ablak vagy bármely WPF vezérlő, de globálisan elérhetők minden létrehozott ablak vagy vezérlő számára a projektumon belül. Ugyanúgy működik, mint abban az esetben amikor egy ablak definíción belül adtuk meg az erőforrást.
<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>
Használata ugyanaz, a WPF automatikusan megy végig a hatökörön belül, a lokális vezérlőktől a létrehozott ablakig, majd az App.xaml file-ig hogy megkeresse a megadott erőforrást.
<Label Content="{StaticResource ComboBoxTitle}" />
Erőforrások a háttér programkódból
Eddig az erőforrásokat közvetlenül az XAML file bejegyzésből vettük. Természetesen az erőforrást megadhatjuk a háttér programkódban is, ami hasznos lehet bizonyos esetekben. Az előző példában láthattuk, hogy tárolhatjuk az erőforrásokat egymástól eltérő helyeken. A következő példában azt fogjuk látni, hogy hogyan érünk el három erőforrást a háttér programkódból, melyek különféle hatókörrel vannak megadva.
App.xaml:
<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>
Window:
<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>
Háttér kód:
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());
}
}
}
Amint a példából látható három különféle "Hello, world!" szöveget tároltunk. Egyik az App.xaml file-ban, a második az ablak definícióban, a harmadik pedig lokálisan a main panel definíciójában. Az interfész egy Button és egy ListBox vezérlőt tartalmaz.
A háttér programkódban lekezeljük a Button kattintás eseményt, amiben a ListBox vezérlőhöz hozzáadjuk mindegyik szting elemet, amint az a képernyőképen látható. A FindResource() metódust alkalmaztuk, ami az erőforrást objektumként adja vissza (ha megtalálja), majd ezután ezt sztring elemmé alakítjuk át az ismert ToString() metódussal.
Figyeljük meg, hogy alkalmaztuk a FindResource() metódust a különböző hatókörökön belül. Először a panelben, utána az ablakban, majd az Application objektumban. Értelmes dolog megkeresni az erőforrást azon a helyen ahol tudjuk hogy található, de amint már említettük, ha nem található, akkor a keresés felfelé halad az öröklési hierarchiában, és alapjában véve a FindResource() metódust alkalmazhatjuk a panel objektumon mindhárom esetben, mert a keresést folytatja felfelé, először az ablakban, majd utána az alkalmazás szintjén ha nem találta még meg az erőforrást.
Az adott keresés nem alkalmazható fordított esetben, vagyis a keresés nem navigál lefelé a hierarchiában. Ez azt jelenti hogy az erőforrás keresése nem alkalmazható az alkalmazás szintjén mert nem találja meg, ha az erőforrás lokálisan az ablakban vagy a vezérlőben lett megadva.