您可以使用 XAML 來定義應用程式的 UI 或資源。 資源通常是您預期使用一次以上之某些對象的定義。 若要稍後參考 XAML 資源,您可以為資源指定一個索引鍵,該索引鍵就像資源的名稱一樣使用。 您可以在整個應用程式或應用程式內的任何 XAML 頁面中參考資源。 您可以使用 Windows 執行時間 XAML 中的 ResourceDictionary 元素來定義資源。 然後,您可以使用 StaticResource 標記延伸 或 ThemeResource 標記延伸來參考資源。
您可能最想要宣告為 XAML 資源的 XAML 元素包括 Style、 ControlTemplate、動畫元件和 Brush 子類別。 在這裡,我們會說明如何定義 ResourceDictionary 和索引鍵資源,以及 XAML 資源如何與您定義為應用程式或應用程式套件一部分的其他資源相關。 我們也說明資源字典進階功能,例如 MergedDictionaries 和 ThemeDictionaries。
先決條件
紮實瞭解 XAML 標記。 建議您閱讀 XAML 概觀。
定義和使用 XAML 資源
XAML 資源是從標記中多次引用的對象。 資源定義於 ResourceDictionary 中,通常是在不同的檔案或標記頁面頂端,如下所示。
<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>
在此範例中:
-
<Page.Resources>…</Page.Resources>
- 定義資源字典。 -
<x:String>
- 定義鍵值為「greeting」的資源。 -
{StaticResource greeting}
- 查詢資源,使用名為「問候語」的索引鍵,該索引鍵被指派給 TextBlock的 Text 屬性。
附註 不要將與 ResourceDictionary 相關的概念與 資源 生成動作、資源 (.resw) 檔案,或在構建生成應用程式套件的程式碼專案時討論的其他「資源」混淆。
資源不一定是字串;它們可以是任何可共享的物件,例如樣式、範本、筆刷和色彩。 不過,控件、圖形和其他 FrameworkElement無法共用,因此無法宣告為可重複使用的資源。 如需共用的詳細資訊,請參閱本主題稍後的 XAML 資源必須可共用 一節。
在這裡,筆刷和字串都會宣告為資源,並由頁面中的控件使用。
<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>
所有資源都需要有金鑰。 鍵值通常是以 x:Key="myString"
定義的字串。 不過,有一些其他方式可以指定鍵值:
- Style 和 ControlTemplate 需要 TargetType,而且如果未指定 x:Key,則會使用 TargetType 做為索引鍵。 在此情況下,索引鍵是實際的 Type 物件,而不是字串。 (請參閱下面的範例)
- 如果未指定 x:Key,則具有 TargetType 的 DataTemplate 資源會使用 TargetType 做為索引鍵。 在此情況下,索引鍵是實際的 Type 物件,而不是字串。
- 可以使用 x:Name ,而不是 x:Key。 不過,x:Name 也會為資源產生後端代碼欄位。 因此,x:Name 的效率比 x:Key 低,因為載入頁面時需要初始化該字段。
StaticResource 標記延伸僅能使用字串名稱(x:Key 或 x:Name)擷取資源。 不過,當 XAML 架構決定要為尚未設定 Style、ContentTemplate 或 ItemTemplate 屬性的控件選擇使用哪種樣式和模板時,也會尋找隱含樣式資源(使用 TargetType 而不是 x:Key 或 x:Name)。
在這裡, Style 具有 typeof(Button)的隱含索引鍵,而且由於頁面底部的 Button 未指定 Style 屬性,因此會尋找 具有 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>
如需隱含樣式及其運作方式的詳細資訊,請參閱 樣式控制 和 控制範本。
在程式代碼中查閱資源
您可以存取資源字典的成員,就像存取任何其他字典一樣。
警告
當您在程式代碼中執行資源查閱時,只會查看字典中的 Page.Resources
資源。 不同於 StaticResource 標記延伸,如果第一個字典中找不到資源,程式代碼就不會回復到 Application.Resources
字典。
此範例示範如何從頁面的資源字典中擷取 redButtonStyle
資源:
<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>();
}
若要從程式代碼中查閱全應用程式資源,請使用 Application.Current.Resources 取得應用程式的資源字典,如下所示。
<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>();
}
您也可以在程式代碼中新增應用程式資源。
這樣做時,請記住兩件事。
- 首先,您必須在任何頁面嘗試使用資源之前新增資源。
- 其次,您無法在應用程式的建構函式中新增資源。
如果您在 Application.OnLaunched 方法中新增資源,可以避免這兩個問題,如下所示。
// 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 …
每個 FrameworkElement 都可以有 ResourceDictionary
FrameworkElement 是一個基類,控制項從中繼承,並且它具有 Resources 屬性。 因此,您可以將本機資源字典新增至任何 FrameworkElement。
在這裡,Page 和 Border 都有資源字典,而且兩者都有稱為「問候」的資源。 名為 'textBlock2' 的 TextBlock 位於 Border 內,因此其資源查閱會先查看 Border 的資源、 Page 的資源,再查看 應用程式 資源。 TextBlock 將顯示「Hola mundo」。
若要從程式代碼存取該專案的資源,請使用該專案的 Resources 屬性。 在程式碼中存取 FrameworkElement的資源,而不是使用 XAML,只會查詢該元素的字典,不會查詢父元素的字典。
<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"))));
}
合併的資源字典
合併的資源字典 將一個資源字典合併到另一個資源字典中,通常在另一個檔案中。
提示 您可以使用 [>] 功能表中的 [新增 > 新專案... 資源字典] 選項,Microsoft 在 Visual Studio 中建立資源 字典檔案。
在這裡,您會在名為 Dictionary1.xaml 的個別 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>
若要使用該字典,請將它與頁面的字典合併:
<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>
以下是此範例中會發生什麼事。 在 <Page.Resources>
中,您會宣告 <ResourceDictionary>
。 當您將資源新增至 <Page.Resources>
時,XAML 架構會隱含地為您建立資源字典;不過,在此情況下,您不需要任何資源字典,而想要包含合併字典的資源字典。
因此,您會宣告 <ResourceDictionary>
,然後將專案新增至其 <ResourceDictionary.MergedDictionaries>
集合。 每一個項目的格式都是 <ResourceDictionary Source="Dictionary1.xaml"/>
。 若要新增多個字典,只要在第一個條目之後新增 <ResourceDictionary Source="Dictionary2.xaml"/>
條目即可。
在 之後 <ResourceDictionary.MergedDictionaries>…</ResourceDictionary.MergedDictionaries>
,您可以選擇性地將其他資源放在主字典中。 您可以使用合併到字典中的資源,就像一般字典一樣。 在上述範例中, {StaticResource brush}
在子/合併字典中尋找資源(Dictionary1.xaml),同時 {StaticResource greeting}
在主頁面字典中尋找其資源。
在資源查閱的過程中,只有在檢查完該 ResourceDictionary 中的所有其他索引資源之後,才會檢查 MergedDictionaries 字典。 搜尋完該層級後,查詢會到達合併的字典,並檢查 MergedDictionaries 中的每個項目。 如果有多個合併字典存在,這些字典會以它們在 MergedDictionaries 屬性中宣告的相反次序進行檢查。 在下列範例中,如果 Dictionary2.xaml 和 Dictionary1.xaml 都宣告了相同的索引鍵,則會先使用 Dictionary2.xaml 中的索引鍵,因為它是 MergedDictionaries 集合中的最後一個。
<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>
在任何一個 ResourceDictionary的範圍內,會檢查字典中的鍵值是否唯一。 不過,該範圍不會延伸到不同 MergedDictionaries 檔案中的不同項目。
您可以利用查閱序列與合併字典範圍內缺乏唯一鍵強制的特性,來創建 ResourceDictionary 資源的後備值序列。 例如,您可以將特定筆刷顏色的使用者喜好設定儲存在序列中最後一個合併的資源字典中,該資源字典會與您的應用程式狀態及使用者喜好設定數據同步。 不過,如果還沒有使用者喜好設定,您可以在初始 MergedDictionaries 檔案中定義一個與 ResourceDictionary 資源相同的鍵字串,它可以作為後援值。 請記住,您在主要資源字典中提供的任何值一律會在檢查合併字典之前進行檢查,因此如果您想要使用後援技術,請勿在主要資源字典中定義該資源。
主題資源和主題字典
ThemeResource 類似於 StaticResource,但當主題改變時,資源查閱會重新評估。
在此範例中,您會將 TextBlock 的前景設定為目前主題中的值。
<TextBlock Text="hello world" Foreground="{ThemeResource FocusVisualWhiteStrokeThemeBrush}" VerticalAlignment="Center"/>
主題字典是一種特殊類型的合併字典,用來保存會隨著使用者裝置上的主題變化而不同的資源。 例如,「淺色」主題可能會使用白色筆刷,而「深色」主題可能會使用深色筆刷。 筆刷會變更其所對應的資源,但除此之外,使用筆刷作為資源的控制項的組成可能相同。 若要在您自己的範本和樣式中重現主題切換行為,請使用 ThemeDictionaries 屬性,而不是使用 MergedDictionaries 屬性將項目合併到主要字典中。
ThemeDictionaries 中的每個 ResourceDictionary 元素都必須具有 x:Key 值。 值是命名相關主題的字串,例如 “Default”、“Dark”、“Light” 或 “HighContrast”。 一般而言, Dictionary1
和 Dictionary2
會定義具有相同名稱但不同值的資源。
在這裡,您使用紅色文字對應淺色主題,藍色文字對應深色主題。
<!-- 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>
在此範例中,您會將 TextBlock 的前景設定為目前主題中的值。
<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>
每當系統偵測到主題變更並使用 ThemeResource 標記延伸 進行參考時,用於資源查閱的主題字典會動態更換。 由系統完成的查閱行為是以將作用中主題對應至特定主題字典 x:Key 為基礎。
檢查在預設 XAML 設計資源中結構化主題字典的方式,非常有用。這些範本類似於 Windows 執行階段預設用於控件的範本。 使用文本編輯器或 IDE,在 \(Program Files)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\<SDK 版本>\Generic 中開啟 XAML 檔案。 請注意如何在 generic.xaml 中先定義主題字典,以及每個主題字典如何定義相同的索引鍵。 然後,每個這樣的鍵都由各種位於主題字典外部且稍後在 XAML 中定義的有鍵元素中的組成元素參考。 另外還有個別的 themeresources.xaml 檔案用於設計,其中只包含主題資源和額外範本,而不是預設控件範本。 主題區域與您在 generic.xaml 中看到的相同。
當您使用 XAML 設計工具來編輯樣式和範本的複本時,設計工具會從 XAML 設計資源字典擷取區段,並將其放置為屬於您應用程式和專案的 XAML 字典元素的本機複本。
如需詳細資訊,以及應用程式可用的主題特定和系統資源清單,請參閱 XAML 主題資源。
XAML 資源參考的查閱行為
查閱行為 是描述 XAML 資源系統如何嘗試尋找 XAML 資源的詞彙。 當索引鍵在應用程式的 XAML 中作為 XAML 資源參考被引用時,就會發生查閱。 首先,資源系統具有可預測的行為,它會根據範圍檢查資源是否存在。 如果在初始範圍中找不到資源,範圍就會展開。 查找行為會於應用程式或系統可能定義 XAML 資源的所有位置與範圍中繼續進行。 如果所有可能的資源查閱嘗試都失敗,則錯誤通常會產生。 在開發程式期間,通常可以消除這些錯誤。
XAML 資源引用的查找行為會以應用實際使用的對象為起點,以及其自己的 Resources 屬性。 如果 ResourceDictionary 存在,則會檢查 ResourceDictionary 是否有具有所要求索引鍵的專案。 此第一層查找很少需要,因為您通常不會在相同物件上定義後再參考資源。 事實上, Resources 屬性通常不存在在這裡。 您幾乎可以在 XAML 中的任何位置參考 XAML 資源,並不侷限於 FrameworkElement 子類別的屬性。
查閱順序接著會檢查應用程式運行時間物件樹狀目錄中的下一個父物件。 如果 FrameworkElement.Resources 存在且包含一個 ResourceDictionary,則會請求具有指定鍵字的字典項目。 如果找到資源,查找程序會停止,然後將物件提供給參考的位置。 否則,查閱行為會向下一個父層級前進,接近物件樹的根。 搜尋會遞迴向上繼續,直到到達 XAML 的根元素為止,並探索完所有可能的即時資源位置。
備註
在頁面根層級定義所有直接資源是常見的作法,這樣可以利用這種資源查閱行為,也符合 XAML 標記語法的慣例。
如果在直接資源中找不到要求的資源,下一個查閱步驟是檢查 Application.Resources 屬性。 Application.Resources 是放置應用程式導覽結構中多個頁面所參考之任何應用程式特定資源的最佳位置。
這很重要
新增至 ResourceDictionary 的資源順序會影響套用資源的順序。
XamlControlsResources
字典會覆寫許多預設資源索引鍵,因此應該先新增至 Application.Resources
,使其不會覆寫應用程式中的任何其他自定義樣式或資源。
控件範本在參考查閱中還有另一個可能的位置:主題字典。 主題字典是具有 ResourceDictionary 元素做為其根目錄的單一 XAML 檔案。 主題字典可能是 Application.Resources 中的合併字典。 主題字典也可能是模板化自訂控件的專屬主題字典。
最後,對平台資源進行資源查詢。 平台資源包括針對每個系統 UI 主題所定義的控制項範本,以及定義您在 Windows 執行時間應用程式中用於 UI 的所有控制件的預設外觀。 平台資源也包含一組與全系統外觀和主題相關的具名資源。 這些資源在技術上是 MergedDictionaries 項目,因此可在應用程式載入之後從 XAML 或程式碼查閱。 例如,系統主題資源中包括一個名為「SystemColorWindowTextColor」的資源,它提供了一個 和 的色彩定義,以便使應用程式的文字色彩與源自作業系統及使用者偏好的系統視窗文字色彩相匹配。 應用程式的其他 XAML 樣式可以參考此樣式,或者您的程式代碼可以取得資源查閱值(並在範例案例中轉換為 Color )。
如需詳細資訊,以及使用 XAML 之 Windows 應用程式可使用的主題特定和系統資源清單,請參閱 XAML 主題資源。
如果上述任何位置中仍然找不到要求的密鑰,就會發生 XAML 剖析錯誤/例外狀況。 在某些情況下,XAML 剖析例外可能是一種運行時期例外,而這種例外無法被 XAML 標記編譯動作或 XAML 設計環境偵測到。
由於資源字典的階層式查閱行為,您可以刻意定義多個資源項目,每個項目都有用作索引鍵的字串值,只要每個資源都在不同的層級定義。 換句話說,雖然索引鍵在任何指定的 ResourceDictionary 內都必須是唯一的,但唯一性需求不會延伸到整個查閱行為序列。 在查閱期間,只有成功擷取的第一個這類物件會用於 XAML 資源參考,然後查閱就會停止。 您可以利用這種行為,在應用程式 XAML 的不同位置通過索引鍵請求相同的 XAML 資源,但根據 XAML 資源參考的範圍以及特定查找行為,可能獲得不同的資源。
轉送 ResourceDictionary 內的參考
特定資源字典內的 XAML 資源參考必須參考已使用索引鍵定義的資源,而且該資源必須以語匯方式出現在資源參考之前。 XAML 資源參考無法解析前向參考。 基於這個理由,如果您使用來自另一個資源內的 XAML 資源參考,則必須設計資源字典結構,讓其他資源所使用的資源先定義在資源字典中。
在應用程式層級定義的資源無法引用即時資源。 這相當於嘗試前向引用,因為應用程式資源實際上在應用程式首次啟動時,以及在載入任何導覽頁面內容之前就已經被處理。 不過,任何立即資源都可以參考應用程式資源,這可以是避免向前參考情況的實用技術。
XAML 資源必須可共用
若要讓物件存在於 ResourceDictionary中,該物件必須 可分享。
需要可共用,因為當應用程式的物件樹狀結構在運行時間建構及使用時,物件無法同時存在於樹狀結構的多個位置中。 在內部,資源系統會在要求每個 XAML 資源時,建立資源值複本,以在應用程式的物件圖形中使用。
ResourceDictionary 和 Windows 執行階段 XAML 一般支援這些物件供共享使用:
- 樣式和範本(Style 和從 FrameworkTemplate 衍生的類別)
- 筆刷和色彩(從 Brush和 Color 值所衍生的類別)
- 動畫類型,包括 分鏡腳本
- 轉換 (衍生自 GeneralTransform的類別)
- 矩陣 和 Matrix3D
- 點 值
- 某些其他與UI相關的結構,例如 厚度 和 CornerRadius
- XAML 內部數據類型
如果您遵循必要的實作模式,也可以使用自定義類型作為可共用的資源。 您可以在支援程式代碼中定義這類類別(或在包含的運行時間元件中),然後將這些類別具現化為資源。 範例包括數據系結的對象數據源和 IValueConverter 實作。
自定義類型必須有預設建構函式,因為這是 XAML 剖析器用來具現化類別的建構函式。 作為資源的自定義型別在其繼承中不能有 UIElement 類別,因為 UIElement 永遠無法共用(它總是代表您運行時應用程式的物件圖中某一位置的一個特定 UI 元素)。
UserControl 使用範圍
UserControl 元素對於資源查閱行為有特殊情況,因為它具有定義範圍和使用範圍固有的概念。 UserControl,從其定義範圍建立 XAML 資源參考,必須能夠在自己的定義範圍的查詢序列中支援該資源的查找,也就是說,它無法存取應用程式資源。 在 UserControl 的使用範圍內,資源參考被視為其使用頁面的根目錄中的查找序列的一部分(就像從已載入的物件樹中建立的其他資源參考一樣),並且可以訪問應用程式資源。
ResourceDictionary 和 XamlReader.Load
您可以使用 ResourceDictionary 作為 XamlReader.Load 方法的根元素或 XAML 輸入的一部分。 如果提交用於載入的 XAML 中所有這類參考都是自成一體,您也可以在該 XAML 中包含 XAML 資源參考。
XamlReader.Load 解析 XAML 時,其執行環境不會察覺到任何其他 ResourceDictionary 物件,包括 Application.Resources。 此外,請勿在提交至 xamlReader.Load的 XAML 內使用
從程式碼中使用 ResourceDictionary
大部分 ResourceDictionary 的案例都是專門用於 XAML 中處理。 您可以將 ResourceDictionary 容器和資源宣告為 UI 定義檔案中的 XAML 檔案或 XAML 節點集。 然後使用 XAML 資源參考,向 XAML 的其他部分要求這些資源。 不過,在某些情況下,您的應用程式可能會想要使用應用程式執行時執行的程式代碼來調整 Application.Current.Resources
。
在 C# 或 Microsoft Visual Basic 程式代碼中,您可以使用索引器 (Item) 參考指定 ResourceDictionary 中的資源。 ResourceDictionary 是字串索引鍵字典,因此索引器會使用字串索引鍵,而不是整數索引。 在 Visual C++ 元件延伸模組 (C++/CX) 程式代碼中,使用 Lookup。
使用程式代碼來檢查或變更 ResourceDictionary時,查找 或 項目 等 API 的行為不會遍歷從立即資源到應用程式資源;這是一種 XAML 剖析器的行為,只會在載入 XAML 頁面時發生。 在運行時間,索引鍵的範圍是與您當時使用的 ResourceDictionary 實例獨立。 不過,該範圍會延伸到 MergedDictionaries。
此外,如果您要求 不存在於 ResourceDictionary 中的密鑰,則可能不會發生錯誤;傳回值可能只提供為 null。 不過,如果您嘗試使用傳回的 Null 做為值,您仍可能會收到錯誤。 錯誤來自於屬性的設定器,而不是 ResourceDictionary 的呼叫。 唯一避免錯誤的方式是,如果屬性接受 Null 做為有效值, 請注意,這種行為與 XAML 在剖析期間的查閱行為形成鮮明對比;在剖析時如果無法從 XAML 中解析提供的鍵,就會導致 XAML 剖析錯誤,即使屬性本來可以接受 null的情況下也是如此。
合併的資源字典會被包含在主要資源字典的索引中的範圍內,以便在執行時參考合併的字典。 換句話說,您可以使用 Item 或 查閱 主字典,來尋找在合併字典中實際定義的任何物件。 在此情況下,查閱行為與剖析時間 XAML 查閱行為類似:如果合併字典中有多個物件,且每個物件都有相同的索引鍵,則會傳回上一個新增字典中的物件。
您可以透過呼叫 Add (C# 或 Visual Basic)或 Insert (C++/CX),將項目新增至現有的 ResourceDictionary。 您可以將項目新增至即時資源或應用程式資源。 這兩個 API 呼叫都需要密鑰,這符合 ResourceDictionary 中每個項目都必須有密鑰的需求。 不過,您在執行時添加到 ResourceDictionary 的項目與 XAML 資源參考無關。 在應用程式載入或偵測到主題變更時,XAML 資源參考的必要查閱會在 XAML 首次剖析時發生。 在運行時間添加到集合的資源當時無法使用,而且修改 ResourceDictionary 的內容不會影響已提取的資源,即使您更改了該資源的值也不會使其失效。
您也可以在運行時從 ResourceDictionary 刪除專案、複製部分或所有項目,或進行其他項目的操作。 ResourceDictionary 的成員列表顯示有哪些 API 可供使用。 請注意,因為 ResourceDictionary 有一個投影 API 來支援其基礎集合介面,因此您的 API 選項會根據您使用 C# 還是 Visual Basic 與 C++/CX 而有所不同。
資源字典和本地化
XAML 的 ResourceDictionary 一開始可能會包含需要本地化的字串。 如果是,請將這些字串儲存為項目資源,而不是儲存在 ResourceDictionary 中。 將字串從 XAML 中取出,並改為為擁有元素提供 x:Uid 指示詞 值。 然後,在資源檔案中定義資源。 請以 XUIDValue的形式提供資源名稱,並提供需要當地語系化的字串作為資源值PropertyName。
自訂資源檢索
針對進階案例,您可以實作類別,其行為可能不同於本主題中所述的 XAML 資源參考查閱行為。 若要這樣做,您需要實作類別 CustomXamlResourceLoader,然後可以透過使用 CustomResource 標記擴展 來存取該行為,而非使用 StaticResource 或 ThemeResource。 大部分的應用程式都不會有需要此情況。 如需詳細資訊,請參閱 CustomXamlResourceLoader。
相關主題