Udostępnij za pośrednictwem


Pack URIs in WPF

W programie Windows Presentation Foundation (WPF) identyfikatory zasobów jednolitych są używane do identyfikowania i ładowania plików na wiele sposobów, w tym następujących:

  • Określanie interfejsu użytkownika (UI), który ma być wyświetlany po pierwszym uruchomieniu aplikacji.

  • Ładowanie obrazów.

  • Przechodzenie do stron.

  • Ładowanie plików danych niebędących plikami wykonywalnymi.

Ponadto identyfikatory URI mogą służyć do identyfikowania i ładowania plików z różnych lokalizacji, w tym następujących:

  • Bieżące zgromadzenie.

  • Zestaw, na który się odwołuje.

  • Lokalizacja względem zestawu.

  • Witryna źródła aplikacji.

Aby zapewnić spójny mechanizm identyfikacji i ładowania tych typów plików z tych lokalizacji, WPF wykorzystuje rozszerzalność schematu identyfikatora URI pakietu . W tym temacie przedstawiono przegląd schematu, opisano sposób konstruowania identyfikatorów URI pakietów dla różnych scenariuszy, omówiono identyfikatory URI bezwzględne i względne oraz rozpoznawanie identyfikatorów URI. Na końcu pokazano, jak używać identyfikatorów URI pakietów zarówno z poziomu znaczników, jak i kodu.

Schemat identyfikatora URI pakietu

Schemat identyfikatora URI pakietu jest używany przez specyfikację Open Packaging Conventions (OPC), która opisuje model organizowania i identyfikowania zawartości. Kluczowymi elementami tego modelu są pakiety i części, w których pakiet jest kontenerem logicznym dla co najmniej jednej części logicznej . Na poniższej ilustracji przedstawiono tę koncepcję.

diagram pakietów i części

Aby zidentyfikować części, specyfikacja OPC wykorzystuje rozszerzalność RFC 2396 (Uniform Resource Identifiers (URI): Składnia ogólna) do definiowania schematu identyfikatorów URI pakietu.

Schemat określony przez identyfikator URI jest definiowany przez jego prefiks; Http, ftp i file są dobrze znanymi przykładami. Schemat identyfikatora URI pakietu używa "pack" jako swojej nazwy i zawiera dwa składniki: autorytet i ścieżkę. Poniżej przedstawiono format identyfikatora URI pakietu.

pack://urzędu/ ścieżki

Urząd określa typ pakietu, w którym znajduje się część, podczas gdy ścieżka określa lokalizację części w pakiecie.

To pojęcie zostało zilustrowane na poniższym rysunku:

relacja między pakietem, urzędem i ścieżką

Pakiety i części są podobne do aplikacji i plików, w których aplikacja (pakiet) może zawierać co najmniej jeden plik (części), w tym:

  • Pliki zasobów, które są kompilowane w lokalnym zestawie.

  • Pliki zasobów skompilowane w odwoływanym zestawie.

  • Pliki zasobów skompilowane do zestawu referencyjnego.

  • Pliki zawartości.

  • Witryna plików źródłowych.

Aby uzyskać dostęp do tych typów plików, platforma WPF obsługuje dwa urzędy: application:/// i siteoforigin:///. Urząd application:/// identyfikuje pliki danych aplikacji, które są znane w czasie kompilacji, w tym pliki zasobów i zawartości. Urząd siteoforigin:/// identyfikuje lokację plików pochodzenia. Zakres każdego urzędu jest pokazany na poniższym rysunku.

Diagram URI pakietu

Notatka

Komponent autorytetu identyfikatora URI pakietu jest osadzonym identyfikatorem URI wskazującym na pakiet i musi być zgodny ze specyfikacją RFC 2396. Ponadto znak "/" musi zostać zastąpiony znakiem ",", a znaki zarezerwowane, takie jak "%" i "?", muszą zostać zabezpieczone. Sprawdź OPC, aby uzyskać szczegółowe informacje.

W poniższych sekcjach opisano sposób konstruowania identyfikatorów URI pakietów przy użyciu tych dwóch urzędów w połączeniu z odpowiednimi ścieżkami do identyfikowania zasobów, zawartości i lokacji plików pochodzenia.

URI pakiety plików zasobów

Pliki zasobów są konfigurowane jako elementy Resource MSBuild i są kompilowane w zestawach. WPF obsługuje konstrukcję identyfikatorów URI pakietów, które mogą służyć do identyfikowania plików zasobów, które są kompilowane w zestawie lokalnym lub kompilowane w zestawie lokalnym, do którego odwołuje się zestaw lokalny.

Plik zasobu zestawu lokalnego

Pakietowy URI dla pliku zasobów skompilowanego w lokalnym zestawie używa następującej autoryzacji i ścieżki:

  • Authority: application:///.

  • Ścieżka: Nazwa pliku zasobów, w tym jego ścieżka, względem katalogu głównego lokalnego projektu assembly.

Poniższy przykład przedstawia identyfikator URI pakietu dla pliku zasobu XAML, który znajduje się w głównym folderze projektu zestawu lokalnego.

pack://application:,,,/ResourceFile.xaml

W poniższym przykładzie przedstawiono identyfikator URI pakietu dla pliku zasobu XAML, który znajduje się w podfolderze folderu projektu zestawu lokalnego.

pack://application:,,,/Subfolder/ResourceFile.xaml

Plik zasobu odwołanego zestawu

Identyfikator URI pakietu dla pliku zasobu skompilowanego w odniesionym zestawie używa następującego autorytetu i ścieżki:

  • Authority: application:///.

  • ścieżka pliku: nazwa pliku zasobu skompilowanego w skojarzonym zestawie. Ścieżka musi być zgodna z następującym formatem:

    AssemblyShortName{; Wersja]{;PublicKey]; component/Path

    • AssemblyShortName: krótka nazwa przywoływanego zestawu.

    • ; Wersja [opcjonalnie]: wersja przywołytowanego zestawu zawierającego plik zasobu. Jest to używane, gdy ładowane są co najmniej dwa zestawy, do których odwołuje się ta sama krótka nazwa.

    • ;PublicKey [opcjonalnie]: klucz publiczny użyty do podpisania odwołanego zestawu. Jest to używane, gdy ładowane są co najmniej dwa zestawy, do których odwołuje się ta sama krótka nazwa.

    • ; komponent: określa, że zestaw, do którego się odwołuje, jest przywoływany z lokalnego zestawu.

    • /Path: nazwa pliku zasobu, w tym jego ścieżka, względem katalogu głównego projektu odwoływanego zestawu.

Poniższy przykład przedstawia pack URI dla pliku zasobu XAML znajdującego się w głównym folderze projektu przywoływanego zestawu.

pack://application:,,,/ReferencedAssembly;component/ResourceFile.xaml

W poniższym przykładzie pokazano pakiet URI dla pliku zasobu XAML, który znajduje się w podfolderze katalogu projektu odniesionego zestawu.

pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml

W poniższym przykładzie przedstawiono identyfikator URI pakietu dla pliku zasobu XAML, który znajduje się w folderze głównym folderu projektu określonego dla określonej wersji zestawu.

pack://application:,,,/ReferencedAssembly;v1.0.0.1;component/ResourceFile.xaml

Należy pamiętać, że składnia identyfikatora URI pakietu w plikach zasobów odwołanego zestawu może być używana tylko z autorytetem application:///. Na przykład następujące elementy nie są obsługiwane w WPF.

pack://siteoforigin:,,,/SomeAssembly;component/ResourceFile.xaml

Identyfikatory URI pakietu zawartości plików

Identyfikator URI pakietu dla pliku zawartości używa następującego autorytetu i ścieżki:

  • Authority: application:///.

  • Ścieżka do pliku: nazwa pliku zawartości, w tym ścieżka pliku względem lokalizacji systemu plików głównego zestawu wykonywalnego aplikacji.

W poniższym przykładzie przedstawiono identyfikator URI pakietu dla pliku zawartości XAML znajdującego się w tym samym folderze co zestaw wykonywalny.

pack://application:,,,/ContentFile.xaml

W poniższym przykładzie przedstawiono identyfikator URI pakietu dla pliku zawartości XAML znajdującego się w podfolderze, który jest powiązany z zestawem wykonywalnym aplikacji.

pack://application:,,,/Subfolder/ContentFile.xaml

Notatka

Nie można przechodzić do plików zawartości HTML. Schemat identyfikatora URI obsługuje tylko nawigację do plików HTML znajdujących się w lokacji źródła.

Identyfikatory URI miejsca pochodzenia pakietu

Identyfikator URI pakietu dla pliku pochodzenia używa następującego autorytetu i ścieżki.

  • Authority: siteoforigin:///.

  • ścieżka: nazwa pliku źródłowego, wraz z jego ścieżką względem lokalizacji, z której został uruchomiony zestaw wykonywalny.

W poniższym przykładzie pokazano identyfikator URI pakietu dla pliku XAML pochodzenia, przechowywanego w lokalizacji, z której uruchamiana jest aplikacja wykonywalna.

pack://siteoforigin:,,,/SiteOfOriginFile.xaml

W poniższym przykładzie pokazano URI pakietu dla pliku pochodzącego z witryny XAML, przechowywanego w podfolderze względem lokalizacji, z której uruchamiany jest plik wykonywalny aplikacji.

pack://siteoforigin:,,,/Subfolder/SiteOfOriginFile.xaml

Pliki stron

Pliki XAML skonfigurowane jako elementy msBuild Page są kompilowane w zestawy w taki sam sposób jak pliki zasobów. W związku z tym elementy Page MSBuild można zidentyfikować przy użyciu identyfikatorów URI pakietów dla plików zasobów.

Typy plików XAML, które są często skonfigurowane jako elementy MSBuildPage, mają jeden z następujących elementów jako element główny:

Bezwzględne a względne identyfikatory URI pakietów

W pełni kwalifikowany identyfikator URI pakietu zawiera schemat, urząd i ścieżkę oraz jest uważany za bezwzględny identyfikator URI pakietu. Dla uproszczenia pracy deweloperów, elementy XAML zazwyczaj umożliwiają ustawianie odpowiednich atrybutów za pomocą względnego pakietu URI, który składa się tylko ze ścieżki.

Na przykład, weźmy następujący bezwzględny identyfikator URI pakietu dla pliku zasobów w lokalnym zestawie.

pack://application:,,,/ResourceFile.xaml

Względny identyfikator URI pakietu, który odwołuje się do tego pliku zasobów, będzie następujący.

/ResourceFile.xaml

Notatka

Ze względu na to, że lokacja plików pochodzenia nie jest skojarzona z zestawami, można odwoływać się do nich tylko za pomocą bezwzględnych identyfikatorów URI pakietów.

Domyślnie względny identyfikator URI pakietu jest traktowany jako relatywny do lokalizacji, w której znajdują się znaczniki lub kod zawierający odwołanie. Jeśli jednak używany jest wiodący ukośnik odwrotny, względne odwołanie URI pakietu jest interpretowane jako względne do katalogu głównego aplikacji. Rozważmy na przykład następującą strukturę projektu.

App.xaml

Page2.xaml

\SubFolder

+ Page1.xaml

+ Page2.xaml

Jeśli Page1.xaml zawiera identyfikator URI, który odwołuje się do Root\SubFolder\Page2.xaml, odwołanie może użyć następującego względnego identyfikatora URI pakietu.

Page2.xaml

Jeśli plik Page1.xaml zawiera identyfikator URI, który odwołuje się do Root\Page2.xaml, można użyć następującego względnego identyfikatora URI pakietu.

/Page2.xaml

Rozpoznawanie identyfikatora URI pakietu

Format identyfikatorów URI pakietów umożliwia, aby identyfikatory URI dla różnych typów plików wyglądały identycznie. Rozważmy na przykład następujący bezwzględny identyfikator URI pakietu.

pack://application:,,,/ResourceOrContentFile.xaml

Ten absolutny identyfikator URI pakietu może odwoływać się do pliku zasobu w lokalnym zestawie lub do pliku zawartości. To samo dotyczy następującego względnego adresu URI.

/ResourceOrContentFile.xaml

Aby określić typ pliku, do którego odwołuje się identyfikator URI pakietu, WPF rozpoznaje identyfikatory URI dla plików zasobów w lokalnych zestawach i plikach zawartości przy użyciu następujących heurystyki:

  1. Przeszukaj metadane zestawu, aby znaleźć atrybut AssemblyAssociatedContentFileAttribute, który pasuje do URI pakietu.

  2. Jeśli zostanie znaleziony atrybut AssemblyAssociatedContentFileAttribute, ścieżka identyfikatora URI pakietu odwołuje się do pliku zawartości.

  3. Jeśli atrybut AssemblyAssociatedContentFileAttribute nie zostanie znaleziony, przeszukaj zestaw plików zasobów, które są kompilowane w lokalnym zestawie.

  4. Jeśli zostanie znaleziony plik zasobu zgodny ze ścieżką identyfikatora URI pakietu, ścieżka identyfikatora URI pakietu odwołuje się do pliku zasobu.

  5. Jeśli zasób nie zostanie znaleziony, utworzony wewnętrznie Uri jest nieprawidłowy.

Rozwiązywanie identyfikatorów URI nie dotyczy identyfikatorów URI, które odnoszą się do następujących:

  • Pliki zawartości w zestawach referencyjnych: te typy plików nie są obsługiwane przez WPF.

  • Pliki osadzone w zestawach, do których odwołuje się odwołanie: identyfikatory URI identyfikujące je są unikatowe, ponieważ zawierają zarówno nazwę przywołytowanego zestawu, jak i sufiks ;component.

  • Lokacja plików pochodzenia: identyfikatory URI, które je identyfikują, są unikatowe, ponieważ są jedynymi plikami, które mogą być zidentyfikowane przez identyfikatory URI pakietów zawierających autorytet siteoforigin:///.

Jednym z uproszczeń, które umożliwia rozwiązywanie identyfikatorów URI pakietów, jest to, że kod może być częściowo niezależny od lokalizacji plików zasobów i zawartości. Jeśli na przykład masz plik zasobu w zestawie lokalnym, który jest ponownie skonfigurowany jako plik zawartości, identyfikator URI pakietu dla zasobu pozostaje taki sam, jak kod, który używa identyfikatora URI pakietu.

Programowanie z użyciem pakietowych URI

Wiele klas WPF implementuje właściwości, które można ustawić za pomocą identyfikatorów URI pakietów, w tym:

Te właściwości można ustawić zarówno na podstawie znaczników, jak i kodu. W tej sekcji przedstawiono podstawowe konstrukcje obu tych rozwiązań, a następnie przedstawiono przykłady typowych scenariuszy.

Używanie identyfikatorów URI pakietów w znacznikach

Identyfikator URI pakietu jest określony w znacznikach, poprzez ustawienie elementu atrybutu z pomocą identyfikatora URI pakietu. Na przykład:

<element attribute="pack://application:,,,/File.xaml" />

Tabela 1 ilustruje różne bezwzględne identyfikatory URI pakietów, które można określić w znacznikach.

Tabela 1: Bezwzględne identyfikatory URI pakietów w kodzie znaczników

Plik Identyfikator URI pakietu bezwzględnego
Plik zasobu — zestaw lokalny "pack://application:,,,/ResourceFile.xaml"
Plik zasobu w podfolderze — lokalna kompilacja "pack://application:,,,/Subfolder/ResourceFile.xaml"
Plik zasobu — zestaw, do których się odwołujesz "pack://application:,,,/ReferencedAssembly;component/ResourceFile.xaml"
Plik zasobu w podfolderze przywoływanego zestawu "pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml"
Plik zasobu w zaktualizowanym zestawie odniesień "pack://application:,,,/ReferencedAssembly;v1.0.0.0;component/ResourceFile.xaml"
Plik treści "pack://application:,,,/ContentFile.xaml"
Plik zawartości w podfolderze "pack://application:,,,/Subfolder/ContentFile.xaml"
Witryna pliku pochodzenia "pack://siteoforigin:,,,/SOOFile.xaml"
Lokalizacja pliku źródłowego w podfolderze "pack://siteoforigin:,,,/Subfolder/SOOFile.xaml"

Tabela 2 ilustruje różne względne identyfikatory URI pakietów, które można określić w znacznikach.

Tabela 2: Względne identyfikatory URI pakietów w markup

Plik Względny identyfikator URI pakietu
Plik zasobu w zestawie lokalnym "/ResourceFile.xaml"
Plik zasobu w podfolderze zestawu lokalnego "/Subfolder/ResourceFile.xaml"
Plik zasobu w odwołanym zestawie "/ReferencedAssembly;component/ResourceFile.xaml"
Plik zasobu w podkatalogu przywoływanego zestawu "/ReferencedAssembly;component/Subfolder/ResourceFile.xaml"
Plik treści "/ContentFile.xaml"
Plik zawartości w podfolderze "/Subfolder/ContentFile.xaml"

Używanie identyfikatorów URI pakietów w kodzie

Identyfikator URI pakietu należy określić w kodzie, instancjonując klasę Uri i przekazując identyfikator URI pakietu jako parametr do konstruktora. Przedstawiono to w poniższym przykładzie.

Uri uri = new Uri("pack://application:,,,/File.xaml");

Domyślnie klasa Uri traktuje URI pakietu jako bezwzględne. W związku z tym jest zgłaszany wyjątek podczas tworzenia wystąpienia klasy Uri przy użyciu względnego identyfikatora URI pakietu.

Uri uri = new Uri("/File.xaml");

Na szczęście przeciążenie Uri(String, UriKind) konstruktora klasy Uri akceptuje parametr typu UriKind, aby umożliwić określenie, czy identyfikator URI pakietu jest bezwzględny czy względny.

// Absolute URI (default)
Uri absoluteUri = new Uri("pack://application:,,,/File.xaml", UriKind.Absolute);
// Relative URI
Uri relativeUri = new Uri("/File.xaml",
                        UriKind.Relative);

Należy określić tylko Absolute lub Relative, gdy masz pewność, że podany identyfikator URI pakietu jest jednym lub drugim. Jeśli nie znasz typu używanego identyfikatora URI pakietu, na przykład gdy użytkownik wprowadza identyfikator URI pakietu podczas działania programu, użyj RelativeOrAbsolute.

// Relative or Absolute URI provided by user via a text box
TextBox userProvidedUriTextBox = new TextBox();
Uri uri = new Uri(userProvidedUriTextBox.Text, UriKind.RelativeOrAbsolute);

Tabela 3 ilustruje różne względne identyfikatory URI pakietów, które można określić w kodzie przy użyciu System.Uri.

Tabela 3: Bezwzględne identyfikatory URI pakietów w kodzie

Plik Bezwzględny identyfikator URI pakietu
Plik zasobu — lokalny zestaw Uri uri = new Uri("pack://application:,,,/ResourceFile.xaml", UriKind.Absolute);
Plik zasobu w podfolderze — zestaw lokalny Uri uri = new Uri("pack://application:,,,/Subfolder/ResourceFile.xaml", UriKind.Absolute);
Plik zasobu — zestaw, do których się odwołujesz Uri uri = new Uri("pack://application:,,,/ReferencedAssembly;component/ResourceFile.xaml", UriKind.Absolute);
Plik zasobu w podfolderze przywoływanego zestawu Uri uri = new Uri("pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml", UriKind.Absolute);
Plik zasobu w zestawie, do których odwołuje się wersja Uri uri = new Uri("pack://application:,,,/ReferencedAssembly;v1.0.0.0;component/ResourceFile.xaml", UriKind.Absolute);
Plik zawartości Uri uri = new Uri("pack://application:,,,/ContentFile.xaml", UriKind.Absolute);
Plik zawartości w podfolderze Uri uri = new Uri("pack://application:,,,/Subfolder/ContentFile.xaml", UriKind.Absolute);
Witryna pliku pochodzenia Uri uri = new Uri("pack://siteoforigin:,,,/SOOFile.xaml", UriKind.Absolute);
Lokalizacja pliku źródłowego w podfolderze Uri uri = new Uri("pack://siteoforigin:,,,/Subfolder/SOOFile.xaml", UriKind.Absolute);

Tabela 4 ilustruje różne względne identyfikatory URI pakietów, które można określić w kodzie przy użyciu System.Uri.

Tabela 4: Względne identyfikatory URI pakietów w kodzie

Plik Względny identyfikator URI pakietu
Plik zasobu — zestaw lokalny Uri uri = new Uri("/ResourceFile.xaml", UriKind.Relative);
Plik zasobu w podfolderze — kompilacja lokalna Uri uri = new Uri("/Subfolder/ResourceFile.xaml", UriKind.Relative);
Plik zasobu — zestaw odwołań Uri uri = new Uri("/ReferencedAssembly;component/ResourceFile.xaml", UriKind.Relative);
Plik zasobu w podfolderze — odwołujący się do zestawu Uri uri = new Uri("/ReferencedAssembly;component/Subfolder/ResourceFile.xaml", UriKind.Relative);
Plik zawartości Uri uri = new Uri("/ContentFile.xaml", UriKind.Relative);
Plik zawartości w podfolderze Uri uri = new Uri("/Subfolder/ContentFile.xaml", UriKind.Relative);

Typowe scenariusze URI pakietu

W poprzednich sekcjach omówiono sposób konstruowania identyfikatorów URI pakietów w celu identyfikowania zasobów, zawartości i lokacji plików pochodzenia. W WPF te konstrukcje są używane na różne sposoby, a w poniższych sekcjach opisano kilka typowych użycia.

Określanie interfejsu użytkownika do pokazania po uruchomieniu aplikacji

StartupUri określa pierwszy interfejs użytkownika, który ma być wyświetlany po uruchomieniu aplikacji WPF. W przypadku aplikacji autonomicznych interfejs użytkownika może być oknem, jak pokazano w poniższym przykładzie.

<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    StartupUri="MainWindow.xaml" />

Aplikacje autonomiczne i aplikacje przeglądarki XAML (XBAPs) mogą również określać stronę jako początkowy interfejs użytkownika, jak pokazano w poniższym przykładzie.

<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    StartupUri="HomePage.xaml" />

Jeśli aplikacja jest aplikacją autonomiczną, a strona jest określona przy użyciu StartupUri, WPF otwiera NavigationWindow do hostowania strony. W przypadku protokołu XBAPs strona jest wyświetlana w przeglądarce hosta.

W poniższym przykładzie pokazano, jak przejść do strony.

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  WindowTitle="Page With Hyperlink"
  WindowWidth="250"
  WindowHeight="250">
<Hyperlink NavigateUri="UriOfPageToNavigateTo.xaml">
  Navigate to Another Page
</Hyperlink>
</Page>

Aby uzyskać więcej informacji na temat różnych sposobów nawigowania w WPF, zobacz Omówienie nawigacji.

Określanie ikony okna

W poniższym przykładzie pokazano, jak za pomocą identyfikatora URI określić ikonę okna.

<Window
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.MainWindow"
    Icon="WPFIcon1.ico">
</Window>

Aby uzyskać więcej informacji, zobacz Icon.

Ładowanie obrazów, audio i plików wideo

WPF umożliwia aplikacjom korzystanie z wielu różnych typów multimediów, z których wszystkie mogą być identyfikowane i ładowane z identyfikatorami URI pakietów, jak pokazano w poniższych przykładach.

<MediaElement Stretch="Fill" LoadedBehavior="Play" Source="pack://siteoforigin:,,,/Media/bee.wmv" />
<MediaElement Stretch="Fill" LoadedBehavior="Play" Source="pack://siteoforigin:,,,/Media/ringin.wav" />
<Image Source="Images/Watermark.png" />

Aby uzyskać więcej informacji na temat pracy z zawartością multimedialną, zobacz Graphics and Multimedia.

Ładowanie słownika zasobów z witryny źródła

Słowniki zasobów (ResourceDictionary) mogą służyć do obsługi motywów aplikacji. Jednym ze sposobów tworzenia motywów i zarządzania nimi jest utworzenie wielu motywów jako słowników zasobów znajdujących się w lokacji pochodzenia aplikacji. Dzięki temu motywy można dodawać i aktualizować bez ponownego komplikowania i ponownego wdrażania aplikacji. Te słowniki zasobów można zidentyfikować i załadować przy użyciu identyfikatorów URI pakietów, które przedstawiono w poniższym przykładzie.

<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    StartupUri="HomePage.xaml">
  <Application.Resources>
    <ResourceDictionary Source="pack://siteoforigin:,,,/PageTheme.xaml" />
  </Application.Resources>
</Application>

Aby zapoznać się z omówieniem stylów w WPF, zobacz sekcję Styling and Templating.

Zobacz też