Odkazy na prostředky ResourceDictionary a XAML

Uživatelské rozhraní nebo prostředky pro vaši aplikaci můžete definovat pomocí XAML. Prostředky jsou obvykle definice některých objektů, které očekáváte, že použijete více než jednou. Pokud chcete odkazovat na prostředek XAML později, zadejte klíč pro prostředek, který funguje jako jeho název. Na prostředek můžete odkazovat v celé aplikaci nebo z libovolné stránky XAML v ní. Prostředky můžete definovat pomocí elementu ResourceDictionary z xaml prostředí Windows Runtime. Pak můžete odkazovat na své prostředky pomocí rozšíření značek StaticResource nebo rozšíření značek ThemeResource.

Prvky XAML, které můžete chtít deklarovat nejčastěji jako prostředky XAML, zahrnují Style, ControlTemplate, animační komponenty a Brush podtřídy. Tady vysvětlujeme, jak definovat ResourceDictionary a klíčové prostředky a jak prostředky XAML souvisejí s dalšími prostředky, které definujete jako součást aplikace nebo balíčku aplikace. Vysvětlujeme také pokročilé funkce slovníku prostředků, jako jsou Sloučené slovníky a Tématické slovníky.

Požadavky

Důkladné porozumění značkám XAML. Doporučujeme přečíst si přehled XAML.

Definování a používání prostředků XAML

Prostředky XAML jsou objekty, na které se odkazuje z kódu více než jednou. Prostředky jsou definovány v ResourceDictionary, obvykle v samostatném souboru nebo v horní části značkovací stránky, jak je uvedeno zde.

<Page
    x:Class="MSDNSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Page.Resources>
        <x:String x:Key="greeting">Hello world</x:String>
        <x:String x:Key="goodbye">Goodbye world</x:String>
    </Page.Resources>

    <TextBlock Text="{StaticResource greeting}" Foreground="Gray" VerticalAlignment="Center"/>
</Page>

V tomto příkladu:

  • <Page.Resources>…</Page.Resources> – Definuje slovník prostředků.
  • <x:String> – definuje zdroj s klíčem "greeting".
  • {StaticResource greeting} - Vyhledá prostředek s klíčem "pozdrav", který je přiřazen k Text vlastnost TextBlock.

Poznámka:

Nezaměňujte koncepty související s ResourceDictionary s akcí sestavení Resource, soubory prostředků (.resw) nebo jinými "zdroji", které jsou diskutovány v kontextu strukturování projektu kódu, který vytváří balíček aplikace.

Prostředky nemusí být řetězce; Můžou se jednat o jakýkoli sdíletelný objekt, jako jsou styly, šablony, štětce a barvy. Ovládací prvky, obrazce a další prvky FrameworkElementvšak nelze sdílet, takže je nelze deklarovat jako opakovaně použitelné prostředky. Další informace o sdílení najdete v části Prostředky XAML musí být sdílené dále v tomto tématu.

V této části se štětec i řetězec deklarují jako prostředky a používají je ovládací prvky na stránce.

<Page
    x:Class="SpiderMSDN.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Page.Resources>
        <SolidColorBrush x:Key="myFavoriteColor" Color="green"/>
        <x:String x:Key="greeting">Hello world</x:String>
    </Page.Resources>

    <TextBlock Foreground="{StaticResource myFavoriteColor}" Text="{StaticResource greeting}" VerticalAlignment="Top"/>
    <Button Foreground="{StaticResource myFavoriteColor}" Content="{StaticResource greeting}" VerticalAlignment="Center"/>
</Page>

Všechny prostředky musí mít klíč. Obvykle je tento klíč řetězcem definovaným pomocí x:Key="myString". Existuje však několik dalších způsobů, jak zadat klíč:

  • style a ControlTemplate vyžadují TargetTypea použijí TargetType jako klíč, pokud není zadán x:Key. V tomto případě je klíčem skutečný objekt Type, nikoli řetězec. (Viz příklady níže)
  • DataTemplate prostředky, které mají TargetType, použijí TargetType jako klíč, pokud není zadán x:Key. V tomto případě je klíčem skutečný objekt Type, nikoli řetězec.
  • x:Name se dá použít místo x:Key. X:Name ale také vygeneruje kód za polem zdroje. V důsledku toho je x:Name méně efektivní než x:Key, protože toto pole musí být inicializováno při načtení stránky.

Rozšíření značek StaticResource může načíst prostředky pouze s řetězcovým názvem (x:Key nebo x:Name). Architektura XAML ale také hledá implicitní prostředky stylu (ty, které používají TargetType místo x:Key nebo x:Name), když se rozhodne, který styl a šablona se má použít pro ovládací prvek, který nenastavil vlastnosti Style a ContentTemplate nebo ItemTemplate .

Tady má Styl implicitní klíč typeof(Button), a protože Tlačítko v dolní části stránky nezadává vlastnost Styl, vyhledá styl s klíčem typu typeof(Button):

<Page
    x:Class="MSDNSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Page.Resources>
        <Style TargetType="Button">
            <Setter Property="Background" Value="Red"/>
        </Style>
    </Page.Resources>
    <Grid>
       <!-- This button will have a red background. -->
       <Button Content="Button" Height="100" VerticalAlignment="Center" Width="100"/>
    </Grid>
</Page>

Další informace o implicitních stylech a jejich fungování najdete v tématu Styling controls and Control templates.

Vyhledání prostředků v kódu

K členům slovníku prostředků se dostanete stejně jako k jakémukoli jinému slovníku.

Výstraha

Při vyhledávání prostředků v kódu se zvažují pouze prostředky ve slovníku Page.Resources. Na rozdíl od rozšíření značek StaticResourcese kód nevrátí do slovníku Application.Resources, pokud se prostředky v prvním slovníku nenajdou.

Tento příklad ukazuje, jak získat prostředek redButtonStyle ze slovníku prostředků stránky.

<Page
    x:Class="MSDNSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Page.Resources>
        <Style TargetType="Button" x:Key="redButtonStyle">
            <Setter Property="Background" Value="red"/>
        </Style>
    </Page.Resources>
</Page>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            Style redButtonStyle = (Style)this.Resources["redButtonStyle"];
        }
    }
    MainPage::MainPage()
    {
        InitializeComponent();
        Windows::UI::Xaml::Style style = Resources().TryLookup(winrt::box_value(L"redButtonStyle")).as<Windows::UI::Xaml::Style>();
    }

Pokud chcete vyhledat prostředky pro celou aplikaci z kódu, použijte Application.Current.Resources ke získání slovníku prostředků aplikace, jak je uvedeno zde.

<Application
    x:Class="MSDNSample.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:SpiderMSDN">
    <Application.Resources>
        <Style TargetType="Button" x:Key="appButtonStyle">
            <Setter Property="Background" Value="red"/>
        </Style>
    </Application.Resources>

</Application>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            Style appButtonStyle = (Style)Application.Current.Resources["appButtonStyle"];
        }
    }
    MainPage::MainPage()
    {
        InitializeComponent();
        Windows::UI::Xaml::Style style = Application::Current().Resources()
                                                               .TryLookup(winrt::box_value(L"appButtonStyle"))
                                                               .as<Windows::UI::Xaml::Style>();
    }

Prostředek aplikace můžete také přidat do kódu.

Při tom je potřeba mít na paměti dvě věci.

  • Nejprve je potřeba přidat prostředky, než se jakákoli stránka pokusí prostředek použít.
  • Zadruhé nemůžete přidávat prostředky v konstruktoru aplikace.

Můžete se vyhnout oběma problémům, pokud prostředek přidáte do metody Application.OnLaunched, jako je tento.

// App.xaml.cs
    
sealed partial class App : Application
{
    protected override void OnLaunched(LaunchActivatedEventArgs e)
    {
        Frame rootFrame = Window.Current.Content as Frame;
        if (rootFrame == null)
        {
            SolidColorBrush brush = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 0, 255, 0)); // green
            this.Resources["brush"] = brush;
            // … Other code that VS generates for you …
        }
    }
}
// App.cpp

void App::OnLaunched(LaunchActivatedEventArgs const& e)
{
    Frame rootFrame{ nullptr };
    auto content = Window::Current().Content();
    if (content)
    {
        rootFrame = content.try_as<Frame>();
    }

    // Do not repeat app initialization when the Window already has content,
    // just ensure that the window is active
    if (rootFrame == nullptr)
    {
        Windows::UI::Xaml::Media::SolidColorBrush brush{ Windows::UI::ColorHelper::FromArgb(255, 0, 255, 0) };
        Resources().Insert(winrt::box_value(L"brush"), winrt::box_value(brush));
        // … Other code that VS generates for you …

Každý FrameworkElement může mít ResourceDictionary.

FrameworkElement je základní třída, z níž dědí ovládací prvky, a má vlastnost nazvanou Resources. Můžete tedy přidat místní slovník prostředků do libovolného FrameworkElement.

V této části mají jak stránka , tak ohraničení slovníky zdrojů, a oba mají zdroj s názvem "pozdrav". TextBlock s názvem "textBlock2" je uvnitř Border, takže jeho vyhledávání prostředků nejprve probíhá v rámci prostředků Border, poté v prostředcích Page, a nakonec v prostředcích aplikace Application. TextBlock bude zobrazovat "Hola mundo".

Pokud chcete získat přístup k prostředkům daného prvku z kódu, použijte vlastnost Resources daného prvku. Přístup k prostředkům FrameworkElementv kódu místo XAML bude vypadat pouze v daném slovníku, nikoli ve slovníkech nadřazeného elementu.

<Page
    x:Class="MSDNSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Page.Resources>
        <x:String x:Key="greeting">Hello world</x:String>
    </Page.Resources>
    
    <StackPanel>
        <!-- Displays "Hello world" -->
        <TextBlock x:Name="textBlock1" Text="{StaticResource greeting}"/>

        <Border x:Name="border">
            <Border.Resources>
                <x:String x:Key="greeting">Hola mundo</x:String>
            </Border.Resources>
            <!-- Displays "Hola mundo" -->
            <TextBlock x:Name="textBlock2" Text="{StaticResource greeting}"/>
        </Border>

        <!-- Displays "Hola mundo", set in code. -->
        <TextBlock x:Name="textBlock3"/>
    </StackPanel>
</Page>

    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            textBlock3.Text = (string)border.Resources["greeting"];
        }
    }
    MainPage::MainPage()
    {
        InitializeComponent();
        textBlock3().Text(unbox_value<hstring>(border().Resources().TryLookup(winrt::box_value(L"greeting"))));
    }

Slovníky sloučených prostředků

Slovník prostředků spojený kombinuje jeden slovník prostředků s jiným, obvykle v jiném souboru.

Tip V sadě Microsoft Visual Studio můžete vytvořit soubor zdrojového slovníku pomocí možnosti Přidat > Novou položku... > Zdrojový slovník v nabídce Projektu.

Zde definujete slovník prostředků v samostatném souboru XAML, který se nazývá Dictionary1.xaml.

<!-- Dictionary1.xaml -->
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MSDNSample">

    <SolidColorBrush x:Key="brush" Color="Red"/>

</ResourceDictionary>

Pokud chcete tento slovník použít, sloučíte ho se slovníkem stránky:

<Page
    x:Class="MSDNSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Page.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Dictionary1.xaml"/>
            </ResourceDictionary.MergedDictionaries>

            <x:String x:Key="greeting">Hello world</x:String>

        </ResourceDictionary>
    </Page.Resources>

    <TextBlock Foreground="{StaticResource brush}" Text="{StaticResource greeting}" VerticalAlignment="Center"/>
</Page>

Tady je postup v tomto příkladu. V <Page.Resources>, deklarujete <ResourceDictionary>. Architektura XAML implicitně vytvoří slovník prostředků pro vás, když přidáte prostředky do <Page.Resources>; v tomto případě však nechcete pouze slovník prostředků, ale takový, který obsahuje sloučené slovníky.

Proto deklarujete <ResourceDictionary>a pak přidáte položky do jeho kolekce <ResourceDictionary.MergedDictionaries>. Každá z těchto položek má tvar <ResourceDictionary Source="Dictionary1.xaml"/>. Pokud chcete přidat více než jeden slovník, stačí přidat <ResourceDictionary Source="Dictionary2.xaml"/> položku za první položku.

Po <ResourceDictionary.MergedDictionaries>…</ResourceDictionary.MergedDictionaries>můžete případně vložit další zdroje do hlavního slovníku. Prostředky ze sloučeného slovníku se používají stejně jako běžný slovník. Ve výše uvedeném příkladu {StaticResource brush} najde zdroj ve sloučeném slovníku Dictionary1.xaml, zatímco {StaticResource greeting} najde zdroj v hlavním slovníku stránky.

V sekvenci vyhledávání prostředků je slovník Sloučené slovníky kontrolován až po kontrole všech ostatních klíčových prostředků této ResourceDictionary. Po prohledání této úrovně vyhledávání dosáhne MergedDictionaries a každá položka v MergedDictionaries je zkontrolována. Pokud existuje více sloučených slovníků, jsou tyto slovníky kontrolovány v opačném pořadí, v jakém jsou deklarovány ve vlastnosti MergedDictionaries. V následujícím příkladu, pokud Dictionary2.xaml a Dictionary1.xaml deklarovali stejný klíč, klíč ze slovníku Dictionary2.xaml se použije přednostně, protože je poslední v Sloučené slovníky set.

<Page
    x:Class="MSDNSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Page.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Dictionary1.xaml"/>
                <ResourceDictionary Source="Dictionary2.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Page.Resources>

    <TextBlock Foreground="{StaticResource brush}" Text="greetings!" VerticalAlignment="Center"/>
</Page>

V rozsahu libovolného ResourceDictionaryse kontroluje jedinečnost klíčů slovníku. Rozsah se však nevztahuje na různé položky v různých souborech MergedDictionaries.

Pomocí kombinace sekvence vyhledávání a chybějícího vynucování jedinečných klíčů napříč obory sloučeného slovníku můžete vytvořit záložní sekvenci hodnot ResourceDictionary prostředků. Uživatelské předvolby pro konkrétní barvu štětce můžete například uložit do posledního sloučeného slovníku prostředků v posloupnosti pomocí slovníku prostředků, který se synchronizuje se stavem vaší aplikace a daty předvoleb uživatele. Pokud však ještě neexistují žádné uživatelské předvolby, můžete definovat stejný řetězec klíče pro prostředek ResourceDictionary v rámci počátečního souboru sloučených slovníků a může být použita jako výchozí hodnota. Mějte na paměti, že každá hodnota, kterou zadáte ve slovníku primárních prostředků, je vždy zaškrtnutá před kontrolou sloučených slovníků, takže pokud chcete použít náhradní techniku, nedefinujte tento prostředek v primárním slovníku prostředků.

Zdroje motivů a slovníky motivů

ThemeResource je podobný StaticResource , ale při změně motivu se vyhledávání prostředků znovu vyhodnocuje.

V tomto příkladu nastavíte barvu popředí TextBlock na hodnotu z aktuálního motivu.

<TextBlock Text="hello world" Foreground="{ThemeResource FocusVisualWhiteStrokeThemeBrush}" VerticalAlignment="Center"/>

Slovník motivů je speciální typ sloučeného slovníku, který obsahuje prostředky, které se liší podle motivu, který uživatel aktuálně používá na svém zařízení. Například "světlý" motiv může používat bílý barevný štětec, zatímco "tmavý" motiv může používat tmavý barevný štětec. Štětec změní zdroj, na který se odkazuje, ale jinak struktura ovládacího prvku, který používá štětec jako zdroj, může zůstat stejná. Chcete-li reprodukovat chování změny témat ve vašich šablonách a stylech, místo použití Sloučené slovníky jako vlastnosti pro propojení položek do hlavních slovníků použijte vlastnost Slovníky motivů.

Každý prvek ResourceDictionary v Slovníky motivů musí mít hodnotu x:Key. Hodnota je řetězec, který pojmenuje příslušný motiv – například "Default", "Dark", "Light" nebo "HighContrast". Obvykle Dictionary1 a Dictionary2 budou definovat prostředky, které mají stejné názvy, ale různé hodnoty.

Tady použijete červený text pro světlý motiv a modrý text pro tmavý motiv.

<!-- Dictionary1.xaml -->
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MSDNSample">

    <SolidColorBrush x:Key="brush" Color="Red"/>

</ResourceDictionary>

<!-- Dictionary2.xaml -->
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MSDNSample">

    <SolidColorBrush x:Key="brush" Color="blue"/>

</ResourceDictionary>

V tomto příkladu nastavíte barvu popředí TextBlock na hodnotu z aktuálního motivu.

<Page
    x:Class="MSDNSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Page.Resources>
        <ResourceDictionary>
            <ResourceDictionary.ThemeDictionaries>
                <ResourceDictionary Source="Dictionary1.xaml" x:Key="Light"/>
                <ResourceDictionary Source="Dictionary2.xaml" x:Key="Dark"/>
            </ResourceDictionary.ThemeDictionaries>
        </ResourceDictionary>
    </Page.Resources>
    <TextBlock Foreground="{StaticResource brush}" Text="hello world" VerticalAlignment="Center"/>
</Page>

Pro slovníky motivů se aktivní slovník, který se má použít pro vyhledávání prostředků, mění dynamicky vždy, když se použije rozšíření značek ThemeResource pro odkaz a systém zjistí změnu motivu. Vyhledávací chování, které systém provádí, je založeno na mapování aktivního tématu na x:Key konkrétního slovníku tématu.

Může být užitečné prozkoumat způsob, jakým jsou slovníky motivů strukturované ve výchozích prostředcích návrhu XAML, které paralelně používají šablony, které prostředí Windows Runtime ve výchozím nastavení používá pro své ovládací prvky. Pomocí textového editoru nebo IDE otevřete soubory XAML v \(Program Files)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\<SDK version>\Generic. Všimněte si, jak jsou slovníky motivu definovány jako první v generic.xaml a jak každý slovník motivu definuje stejné klíče. Na každý takový klíč se pak odkazuje prvky složení v různých klíčových prvcích, které jsou mimo slovníky motivu a které jsou definovány později v XAML. Existuje také samostatný soubor themeresources.xaml, který obsahuje pouze zdroje motivu a další šablony, nikoli výchozí šablony ovládacích prvků. Oblasti motivu jsou duplikáty toho, co byste viděli v generic.xaml.

Když použijete nástroje pro návrh XAML k úpravě kopií stylů a šablon, nástroje pro návrh extrahují oddíly ze slovníků zdrojů návrhu XAML a umístí je jako místní kopie elementů slovníku XAML, které jsou součástí vaší aplikace a projektu.

Další informace a seznam systémových prostředků a prostředků specifických pro motiv, které jsou k dispozici pro vaši aplikaci, najdete v tématu prostředky motivu XAML.

Chování vyhledávání pro odkazy na prostředky XAML

chování vyhledávání je termín, který popisuje, jak se systém prostředků XAML pokouší najít prostředek XAML. K vyhledávání dochází, když je na klíč odkazováno jako na prostředek XAML z nějaké části XAML kódu aplikace. Za prvé, systém prostředků má předvídatelné chování, ve kterém bude kontrolovat existenci prostředku na základě rozsahu. Pokud se prostředek v počátečním oboru nenajde, rozsah se rozšíří. Chování vyhledávání pokračuje napříč všemi umístěními a obory, které mohou být definovány aplikací nebo systémem prostředkem XAML. Pokud všechny možné pokusy o vyhledávání prostředků selžou, často dojde k chybě. Tyto chyby je obvykle možné odstranit během procesu vývoje.

Vyhledávací chování pro odkazy na prostředky XAML začíná objektem, ve kterém je skutečně využito, a jeho vlastností Resources. Pokud existuje ResourceDictionary, zkontroluje ResourceDictionary položku s požadovaným klíčem. Tato první úroveň vyhledávání je zřídka relevantní, protože obvykle nedefinujete a pak odkazujete na prostředek na stejném objektu. Vlastnost Resources ve skutečnosti často neexistuje. Odkazy na prostředky XAML můžete vytvářet téměř odkudkoli v JAZYCE XAML; nejste omezeni na vlastnosti podtříd FrameworkElement .

Sekvence vyhledávání pak zkontroluje další nadřazený objekt ve stromu objektů za běhu aplikace. Pokud FrameworkElement.Resources existuje a obsahujeResourceDictionary , je požadována položka slovníku se zadaným řetězcem klíče. Pokud se prostředek najde, sekvence vyhledávání se zastaví a objekt se poskytne na místo, kde byl odkaz vytvořen. V opačném případě chování vyhledávání přejde na další nadřazenou úroveň směrem k kořenu stromu objektů. Hledání pokračuje rekurzivně směrem nahoru, dokud není dosažen kořenový prvek XAML, čímž se vyčerpá hledání všech možných přímých umístění prostředků.

Poznámka:

Běžným postupem je definovat veškeré okamžité prostředky na kořenové úrovni stránky, aby se využilo tohoto chování při vyhledávání prostředků a také jako konvence stylu zápisu XAML.

Pokud požadovaný prostředek není nalezen v bezprostředních prostředcích, dalším krokem vyhledávání je kontrola vlastnosti Application.Resources. Application.Resources je nejlepším místem pro umístění prostředků specifických pro aplikaci, na které odkazuje více stránek v navigační struktuře vaší aplikace.

Důležité

Pořadí prostředků přidaných do ResourceDictionary má vliv na pořadí, ve kterém se používají. Slovník XamlControlsResources přepíše mnoho výchozích klíčů prostředků, a proto by se měl nejprve přidat do Application.Resources, aby nedošlo k přepsání žádných jiných vlastních stylů nebo prostředků v aplikaci.

Šablony ovládacích prvků mají v referenčním vyhledávání další možné umístění: slovníky motivů. Slovník motivů je jeden soubor XAML, který má element ResourceDictionary jako jeho kořen. Slovník motivů může být sloučený slovník z Application.Resources. Slovník motivů může být také specifický pro přizpůsobený řídicí prvek, který používá šablony.

Nakonec dojde k vyhledání prostředků v rámci zdrojů platformy. Prostředky platformy zahrnují šablony ovládacích prvků definované pro každý motiv uživatelského rozhraní systému a definují výchozí vzhled všech ovládacích prvků, které používáte pro uživatelské rozhraní v aplikaci Windows Runtime. Prostředky platformy také obsahují sadu pojmenovaných prostředků, které se týkají vzhledu a témat celého systému. Tyto prostředky jsou technicky položkou sloučených slovníků a, a proto jsou k dispozici pro vyhledávání z XAML nebo prostřednictvím kódu po spuštění aplikace. Například prostředky systémového motivu obsahují prostředek s názvem "SystemColorWindowTextColor", který poskytuje definici Color pro sladění barvy textu aplikace s barvou textu systémového okna, přičemž tato barva pochází z operačního systému a uživatelských předvoleb. Jiné styly XAML pro vaši aplikaci mohou odkazovat na tento styl nebo kód může získat hodnotu zdroje (a přetypovat ji na typ Barva podle příkladu s a).

Pokud potřebujete více informací a seznam prostředků specifických pro motiv a systémových prostředků, které jsou dostupné pro aplikaci Windows využívající XAML, podívejte se na téma prostředky motivu XAML.

Pokud požadovaný klíč stále není nalezen v žádném z těchto umístění, dojde k chybě nebo výjimce XAML. Za určitých okolností může být výjimka analýzy XAML výjimkou za běhu, která není zjištěna akcí kompilace značek XAML nebo prostředím návrhu XAML.

Vzhledem k chování vrstveného vyhledávání slovníků prostředků můžete záměrně definovat více položek prostředků, které mají stejnou řetězcovou hodnotu jako klíč, pokud je každý prostředek definovaný na jiné úrovni. Jinými slovy, i když klíče musí být jedinečné v rámci libovolného resourcedictionary, požadavek na jedinečnost se nevztahuje na posloupnost chování vyhledávání jako celek. Při vyhledávání se pro odkaz na prostředky XAML použije pouze první takový objekt, který se úspěšně načte, a pak se vyhledávání zastaví. Toto chování můžete použít k vyžádání stejného prostředku XAML podle klíče na různých pozicích v XAML vaší aplikace, ale obdržet různé prostředky v závislosti na kontextu, ze kterého byl proveden odkaz na prostředek XAML, a na chování konkrétního vyhledávání.

Předávání odkazů v rámci ResourceDictionary

Odkazy na prostředky XAML v určitém slovníku prostředků musí odkazovat na prostředek, který již byl definován pomocí klíče, a tento prostředek se musí objevit lexicky před odkazem na prostředek. Dopředné odkazy nelze vyřešit odkazem na prostředek XAML. Z tohoto důvodu platí, že pokud používáte odkazy na prostředky XAML z jiného prostředku, je nutné navrhnout strukturu slovníku prostředků tak, aby prostředky používané jinými prostředky byly definovány jako první ve slovníku prostředků.

Prostředky definované na úrovni aplikace nemůžou odkazovat na okamžité prostředky. To je ekvivalentem pokusu o přeposlání odkazu, protože prostředky aplikace se ve skutečnosti zpracovávají jako první (při prvním spuštění aplikace a před načtením obsahu navigační stránky). Jakýkoli okamžitý zdroj ale může odkazovat na zdroj aplikace, a může to být užitečná technika pro zabránění situacím, kdy je potřeba odkazu na něco, co následuje.

Prostředky XAML musí být sdíletelné.

Aby objekt existoval vResourceDictionary , musí být tento objekt sdíletelné.

Sdílení je povinné, protože když je objektový strom aplikace vytvořen a používán za běhu, objekty nemohou existovat ve více umístěních ve stromu. Systém prostředků interně vytvoří kopie hodnot prostředků, které se po vyžádání jednotlivých prostředků XAML použijí v grafu objektů vaší aplikace.

Soubor RESOURCEDictionary a Windows Runtime XAML obecně podporují tyto objekty pro použití ke sdílení:

Vlastní typy můžete použít také jako prostředek, který je možné sdílet, pokud dodržujete nezbytné vzory implementace. Takové třídy definujete v backingovém kódu (nebo v komponentách modulu runtime, které zahrnete) a pak tyto třídy vytvoříte v XAML jako prostředek. Příklady zahrnují zdroje dat objektů a implementace IValueConverter pro datovou vazbu.

Vlastní typy musí mít výchozí konstruktor, protože to je to, co analyzátor XAML používá k vytvoření instance třídy. Vlastní typy používané jako prostředky nemohou mít UIElement třídy v rámci dědičnosti, protože UIElement nemůže být nikdy sdílen (vždy představuje přesně jeden prvek uživatelského rozhraní, který existuje na jedné pozici v objektovém grafu běhové aplikace).

Rozsah využití UserControl

Element UserControl má specifický případ pro chování vyhledávání prostředků, protože má vlastní koncepty oboru definice a rozsahu použití. UserControl, který vytváří odkaz na prostředek XAML z jeho oboru definice musí být schopen podporovat vyhledávání tohoto prostředku v rámci vlastní sekvence vyhledávání v oboru definic – to znamená, že nemůže získat přístup k prostředkům aplikace. Z oboru použití UserControl se odkaz na prostředek považuje za odkaz na prostředek ve vyhledávací sekvenci směrem ke kořenovému adresáři stránky využití (stejně jako jakýkoli jiný odkaz na prostředek vytvořený z objektu v načteném stromu objektů) a má přístup k prostředkům aplikace.

ResourceDictionary a XamlReader.Load

ResourceDictionary můžete použít buď jako kořen, nebo jako součást vstupu XAML pro metodu XamlReader.Load. Odkazy na prostředky XAML můžete také zahrnout do tohoto XAML, pokud jsou všechny tyto odkazy zcela samostatné v XAML odeslaném ke zpracování. XamlReader.Load analyzuje XAML v kontextu, který nezná žádné jiné objekty ResourceDictionary , ani Application.Resources. Nepoužívejte také {ThemeResource} z xaml odeslané do XamlReader.Load.

Použití objektu ResourceDictionary z kódu

Většina scénářů pro ResourceDictionary se zpracovává výhradně v JAZYCE XAML. Deklarujete ResourceDictionary kontejner a prostředky v něm jako soubor XAML nebo sadu uzlů XAML v definičním souboru uživatelského rozhraní. Pak použijete odkazy na prostředky XAML k vyžádání těchto prostředků z jiných částí XAML. Přesto existují určité scénáře, kdy může vaše aplikace chtít upravit obsah ResourceDictionary pomocí kódu, který se spustí, když je aplikace spuštěná, nebo alespoň dotazovat obsah ResourceDictionary , aby se zjistilo, jestli už je prostředek definovaný. Tato volání kódu jsou provedena v instanci ResourceDictionary, takže je třeba nejprve načíst jednu – buď okamžitou ResourceDictionary někde ve stromu objektů získáním FrameworkElement.Resourcesnebo Application.Current.Resources.

V jazyce C# můžete odkazovat na prostředek v daném ResourceDictionary pomocí indexeru (Položka). ResourceDictionary je slovník s klíči typu řetězec, takže indexátor používá řetězcový klíč místo celočíselného indexu. V kódu rozšíření komponent Visual C++ (C++/CX) použijte Lookup.

Při použití kódu k prozkoumání nebo změně ResourceDictionarychování rozhraní API, jako je vyhledávání nebo Položka neprocházejí z okamžitých prostředků do prostředků aplikace; to je chování analyzátoru XAML, ke kterému dochází pouze při načítání stránek XAML. V době běhu je rozsah klíčů samostatný na instanci ResourceDictionary, kterou používáte v daném okamžiku. Tento obor se však vztahuje na Sloučené slovníky.

Pokud také požádáte o klíč, který v ResourceDictionary neexistuje, pravděpodobně nedojde k chybě; návratová hodnota může být jednoduše zadaná jako null. Přesto se může zobrazit chyba, pokud se pokusíte použít vrácenou hodnotu null jako hodnotu. Chyba by pocházela z nastavovače vlastnosti, ne z vašeho volání ResourceDictionary. Jediný způsob, jak se vyhnout chybě, je, pokud vlastnost přijala hodnotu null jako platnou hodnotu. Všimněte si, jak toto chování kontrastuje s chováním vyhledávání XAML při analýze XAML; nevyřešení zadaného klíče z XAML v době analýzy způsobí chybu analýzy XAML, a to i v případech, kdy vlastnost mohla přijmout null.

Slovníky sloučených prostředků jsou zahrnuty do rozsahu indexu primárního slovníku prostředků, který referuje na sloučený slovník během běhu programu. Jinými slovy, můžete použít položku nebo vyhledávání primárního slovníku a najít všechny objekty, které byly skutečně definovány ve sloučeném slovníku. V tomto případě chování vyhledávání vypadá podobně jako chování vyhledávání XAML v čase parse-time: pokud ve sloučených slovníkech existuje více objektů, které mají stejný klíč, vrátí se objekt z posledního přidaného slovníku.

Můžete přidávat položky do existujícího ResourceDictionary voláním příkazu Přidat nebo Vložit (C++/CX). Položky můžete přidat k okamžitým prostředkům nebo prostředkům aplikace. Každé z těchto volání API vyžaduje klíč, což splňuje požadavek, aby každá položka ve ResourceDictionary měla svůj klíč. Položky, které přidáte do ResourceDictionary za běhu, nejsou relevantní pro odkazy na prostředky XAML. K nezbytnému vyhledávání odkazů na prostředky XAML dochází při prvotním zpracování XAML během načítání aplikace (nebo při zjištění změny motivu). Prostředky přidané do kolekcí za běhu nebyly dostupné a změna ResourceDictionary nezpůsobí neplatnost již načteného prostředku, i když změníte hodnotu tohoto prostředku.

Můžete také odebrat položky ze slovníku prostředků za běhu, vytvářet kopie některých nebo všech položek nebo provádět jiné operace. Seznam členů pro ResourceDictionary označuje, která rozhraní API jsou k dispozici. Vzhledem k tomu, že ResourceDictionary má předpokládané rozhraní API pro podporu jeho podkladových rozhraní kolekce, liší se možnosti rozhraní API v závislosti na tom, jestli používáte jazyk C# nebo Visual Basic a C++/CX.

ResourceDictionary a lokalizace

Zpočátku může ResourceDictionary v XAML obsahovat řetězce určené k lokalizaci. Pokud ano, uložte tyto řetězce jako prostředky projektu místo do ResourceDictionary. Vyjměte řetězce z XAML a místo toho dejte vlastnícího elementu x:Uid direktivě hodnotu. Pak definujte prostředek v souboru prostředků. Zadejte název prostředku ve formuláři XUIDValue.PropertyName a hodnotu prostředku řetězce, který by měl být lokalizován.

Vlastní vyhledávání zdrojů

V případě pokročilých scénářů můžete implementovat třídu, která má jiné chování než chování vyhledávání odkazů na prostředky XAML popsané v tomto tématu. Chcete-li to provést, implementujete třídu CustomXamlResourceLoadera pak k němu můžete přistupovat pomocí rozšíření značky CustomResource pro odkazy na zdroje místo použití StaticResource nebo ThemeResource. Většina aplikací nebude mít scénáře, které to vyžadují. Další informace najdete v CustomXamlResourceLoader.