This article has been localized into Slovak by the community.
Resources (zdroje)
WPF predstavuje veľmi užitočný koncept: Schopnosť uchovávať dáta ako zdroje, lokálne pre ovládacie prvky, lokálne pre celé okno, alebo globálne pre celú aplikáciu. Zdroje môžu byť skoro všetko, čo chcete, od aktuálnych informácií až po hierarchiu ovládacích prvkov WPF. To vám umožní umiestniť dáta na jednom mieste a potom ich viackrát použiť na iných miestach, čo je veľmi užitočné.
Tento koncept sa používa hlavne pre štýly a šablóny (styles, templates), o ktorých budeme hovoriť neskôr v tomto tútoriály. Ale Resources môžete používať aj pre mnohé iné veci. Ukážeme si to na jednoduchom príklade:
<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>
Resources sú zadané kľúčom pomocou atribútu x: Key, ktorý vám umožňuje odkazovať z iných častí aplikácie pomocou tohto kľúča a pomocou značky StaticResource. V tomto príklade je uložený jednoduchý reťazec, ktorý potom použijeme v dvoch rôznych ovládacích prvkoch TextBlock.
StaticResource vs. DynamicResource
V doterajších príkladoch som použil značku StaticResource ako odkaz na zdroj. Existuje však alternatíva vo forme DynamicResource.
Hlavným rozdielom je, že statický prostriedok je vyriešený iba raz pri načítaní súboru XAML. Ak sa zdroj neskôr zmení pri použití StaticResource nedôjde už k žiadnej zmene.
DynamicResource na druhej strane sú použité, akonáhle je to skutočne potrebné, a potom znova, ak sa zdroj zmení. Myslite na to, že je to statická hodnota verzus väzba na funkciu, ktorá sleduje túto hodnotu a pošle ju vždy, keď je zmenená - nie je to presne to, ako to funguje, ale malo by vám to dať lepšiu predstavu o tom, kedy čo použiť. Dynamické zdroje vám tiež umožňujú využívať zdroje, ktoré ešte nie sú vytvorené, napr. ak ich pridáte v kóde pri spustení aplikácie.
Ďalšie typy zdrojov
Zdieľanie jednoduchého reťazca bolo jednoduché, ale môžete urobiť oveľa viac. V ďalšom príklade uložíme pole reťazcov spolu s gradientným štetcom na vykreslenie pozadia. To by malo dať celkom dobrú predstavu o tom, čo môžete robiť so zdrojmi:
<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>
Pridali sme niekoľko ďalších zdrojov, takže naše okno teraz obsahuje jednoduchý reťazec, pole reťazcov a LinearGradientBrush (gradient štetec). Reťazec je použitý na kontrolku label, pole reťazcov sú použité ako položky pre ovládací prvok ComboBox a gradient štetec ako pozadie okna. Takže, ako vidíte, skoro všetko sa dá uložiť ako zdroj.
Miestne zdroje a zdroje aplikácie
Nateraz máme uložené zdroje na úrovni okna, čo znamená, že k nim máte prístup z celého okna.
Ak potrebujete len určitý prostriedok pre určitú kontrolku, môžete ho pridať priamo do tohto ovládacieho prvku namiesto do okna. Funguje to tak isto, jediným rozdielom je to, že teraz môžete získať prístup len z vnútra rozsahu ovládacieho prvku, do ktorého ste ho umiestnili:
<StackPanel Margin="10">
<StackPanel.Resources>
<sys:String x:Key="ComboBoxTitle">Items:</sys:String>
</StackPanel.Resources>
<Label Content="{StaticResource ComboBoxTitle}" />
</StackPanel>
V tomto prípade pridáme zdroj do prvku StackPanel a potom ho použijeme v jeho podriadenom prvku Label. Iné ovládacie prvky vnútri kontrolky StackPanel by mohli mať tiež prístup k tomuto zdroju. Ovládacie prvky mimo StackPanel by nemali k nemu prístup.
Ak potrebujete možnosť získať prístup k zdroju z viacerých okien, je to tiež možné. Súbor App.xaml môže obsahovať zdroje rovnako ako okno a akýkoľvek druh ovládacích prvkov WPF, a keď ich uložíte do súboru App.xaml, sú globálne dostupné vo všetkých oknách a používateľských ovládacích prvkoch projektu. Funguje to presne tak, ako pri ukladaní a používaní z okna:
<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>
Použitie je rovnaké - WPF automaticky hľadá postupne v ovládacom prvku, v okne a potom v súbore App.xaml, aby našiel daný zdroj:
<Label Content="{StaticResource ComboBoxTitle}" />
Zdroje z kódu na pozadí
Zatiaľ sme pristupovali ku všetkým našim zdrojom priamo z XAML použitím značky. Prístup možete získať samozrejme aj z kódu, čo môže byť užitočné v niektorých situáciách. V predchádzajúcom príklade sme si ukázali ako môžeme ukladať zdroje na rôznych miestach, takže v tomto príklade budeme pristupovať k trom rôznym zdrojom z kódu, každý z nich je uložený v inde:
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>
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());
}
}
}
Takže, ako vidíte, ukladáme tri rôzne reťazce "Ahoj, svet!": jeden v App.xaml, jeden v okne a jeden v prvku hlavný panel. Rozhranie pozostáva z ovládacích prvkov Button a ListBox.
V kóde vytvorím obsluhu udalosti kliknutia na tlačidlo, v ktorej pridáme každý textový reťazec do prvku ListBox, ako je vidieť na snímke obrazovky. Používame metódu FindResource(), ktorá vráti zdroj ako objekt (ak sa nájde) a potom ho prevedieme na reťazec pomocou metódy ToString().
Všimnite si, ako používame metódu FindResource() v rôznych oblastiach - najprv na paneli, potom na okne a potom na aktuálnom objekte Application. Ak nie je nájdený zdroj, vyhľadávanie postupuje hierarchicky, takže hlavne by sme mohli použiť metódu FindResource() na paneli vo všetkých troch prípadoch, pretože by pokračoval až k oknu a neskôr až na úroveň aplikácie.
To však neplatí opačným smerom - vyhľadávanie sa nepohybuje smerom nadol, takže nemôžete začať hľadať zdroj na úrovni aplikácie, ak bola definovaná lokálne pre ovládací prvok alebo pre okno.