A .NET Multi-platform App UI (.NET MAUI) ResourceDictionary is a repository for resources that are used by a .NET MAUI app. Typical resources that are stored in a ResourceDictionary include styles, control templates, data templates, converters, and colors.
XAML resources that are stored in a ResourceDictionary can be referenced and applied to elements by using the StaticResource or DynamicResource markup extension. In C#, resources can also be defined in a ResourceDictionary and then referenced and applied to elements by using a string-based indexer.
Tip
In Visual Studio, a XAML-based ResourceDictionary file that's backed by a code-behind file can be added to your project by the .NET MAUI ResourceDictionary (XAML) item template.
Create resources
Every VisualElement derived object has a Resources property, which is a ResourceDictionary that can contain resources. Similarly, an Application derived object has a Resources property, which is a ResourceDictionary that can contain resources.
A .NET MAUI app can contain only a single class that derives from Application, but often makes use of many classes that derive from VisualElement, including pages, layouts, and views. Any of these objects can have its Resources property set to a ResourceDictionary containing resources. Choosing where to put a particular ResourceDictionary impacts where the resources can be used:
Resources in a ResourceDictionary that is attached to a view, such as Button or Label, can only be applied to that particular object.
Resources in a ResourceDictionary attached to a layout, such as StackLayout or Grid, can be applied to the layout and all the children of that layout.
Resources in a ResourceDictionary defined at the page level can be applied to the page and to all its children.
Resources in a ResourceDictionary defined at the application level can be applied throughout the app.
With the exception of implicit styles, each resource in resource dictionary must have a unique string key that's defined with the x:Key attribute.
The following XAML shows resources defined in an application level ResourceDictionary in the App.xaml file:
In this example, the resource dictionary defines a Thickness resource, multiple Color resources, and two implicit Style resources.
Important
Inserting resources directly between the Resources property-element tags automatically creates a ResourceDictionary object. However, it's also valid to place all resources between optional ResourceDictionary tags.
Consume resources
Each resource has a key that is specified using the x:Key attribute, which becomes its dictionary key in the ResourceDictionary. The key is used to reference a resource from the ResourceDictionary with the StaticResource or DynamicResource XAML markup extension.
The StaticResource markup extension is similar to the DynamicResource markup extension in that both use a dictionary key to reference a value from a resource dictionary. However, while the StaticResource markup extension performs a single dictionary lookup, the DynamicResource markup extension maintains a link to the dictionary key. Therefore, if the dictionary entry associated with the key is replaced, the change is applied to the visual element. This enables runtime resource changes to be made in an app. For more information about markup extensions, see XAML markup extensions.
The following XAML example shows how to consume resources, and also define an additional resource in a StackLayout:
In this example, the ContentPage object consumes the implicit style defined in the application level resource dictionary. The StackLayout object consumes the PageMargin resource defined in the application level resource dictionary, while the Button object consumes the implicit style defined in the StackLayout resource dictionary. This results in the appearance shown in the following screenshot:
Important
Resources that are specific to a single page shouldn't be included in an application level resource dictionary, as such resources will then be parsed at app startup instead of when required by a page. For more information, see Reduce the application resource dictionary size.
Resource lookup behavior
The following lookup process occurs when a resource is referenced with the StaticResource or DynamicResource markup extension:
The requested key is checked for in the resource dictionary, if it exists, for the element that sets the property. If the requested key is found, its value is returned and the lookup process terminates.
If a match isn't found, the lookup process searches the visual tree upwards, checking the resource dictionary of each parent element. If the requested key is found, its value is returned and the lookup process terminates. Otherwise the process continues upwards until the root element is reached.
If a match isn't found at the root element, the application level resource dictionary is examined.
If a match still isn't found, a XamlParseException is thrown.
Therefore, when the XAML parser encounters a StaticResource or DynamicResource markup extension, it searches for a matching key by traveling up through the visual tree, using the first match it finds. If this search ends at the page and the key still hasn't been found, the XAML parser searches the ResourceDictionary attached to the App object. If the key still isn't found, an exception is thrown.
Override resources
When resources share keys, resources defined lower in the visual tree will take precedence over those defined higher up. For example, setting an AppBackgroundColor resource to AliceBlue at the application level will be overridden by a page level AppBackgroundColor resource set to Teal. Similarly, a page level AppBackgroundColor resource will be overridden by a layout or view level AppBackgroundColor resource.
Stand-alone resource dictionaries
A ResourceDictionary can also be created as a stand-alone XAML file that isn't backed by a code-behind file. To create a stand-alone ResourceDictionary, add a new ResourceDictionary file to the project with the .NET MAUI ResourceDictionary (XAML) item template and delete its code-behind file. Then, in the XAML file remove the x:Class attribute from the ResourceDictionary tag near the start of the file. In addition, add <?xaml-comp compile="true" ?> after the XML header to ensure that the XAML will be compiled.
A ResourceDictionary can also be created as a stand-alone XAML file that isn't backed by a code-behind file. To create a stand-alone ResourceDictionary, add a new ResourceDictionary file to the project with the .NET MAUI ResourceDictionary (XAML) item template and delete its code-behind file. Then, in the XAML file remove the x:Class attribute from the ResourceDictionary tag near the start of the file. By default, a stand-alone ResourceDictionary has its XAML compiled, unless <?xaml-comp compile="false" ?> is specified after the XML header.
In this example, the ResourceDictionary contains a single resource, which is an object of type DataTemplate. MyResourceDictionary.xaml can be consumed by merging it into another resource dictionary.
<ContentPage ...>
<ContentPage.Resources>
<!-- Add more resources here -->
<ResourceDictionary Source="MyResourceDictionary.xaml" />
<!-- Add more resources here -->
</ContentPage.Resources>
...
</ContentPage>
This syntax does not instantiate the MyResourceDictionary class. Instead, it references the XAML file. For that reason, when setting the Source property, a code-behind file isn't required, and the x:Class attribute can be removed from the root tag of the MyResourceDictionary.xaml file.
Important
The ResourceDictionary.Source property can only be set from XAML.
Merge resource dictionaries from other assemblies
A ResourceDictionary can also be merged into another ResourceDictionary by adding it into the MergedDictionaries property of the ResourceDictionary. This technique allows resource dictionaries to be merged, regardless of the assembly in which they reside. Merging resource dictionaries from external assemblies requires the ResourceDictionary to have a build action set to MauiXaml, to have a code-behind file, and to define the x:Class attribute in the root tag of the file.
Warning
The ResourceDictionary class also defines a MergedWith property. However, this property has been deprecated and should no longer be used.
The following code example shows two resource dictionaries being added to the MergedDictionaries collection of a page level ResourceDictionary:
<ContentPage ...
xmlns:local="clr-namespace:ResourceDictionaryDemo"
xmlns:theme="clr-namespace:MyThemes;assembly=MyThemes">
<ContentPage.Resources>
<ResourceDictionary>
<!-- Add more resources here -->
<ResourceDictionary.MergedDictionaries>
<!-- Add more resource dictionaries here -->
<local:MyResourceDictionary />
<theme:DefaultTheme />
<!-- Add more resource dictionaries here -->
</ResourceDictionary.MergedDictionaries>
<!-- Add more resources here -->
</ResourceDictionary>
</ContentPage.Resources>
...
</ContentPage>
In this example, a resource dictionary from the same assembly, and a resource dictionary from an external assembly, are merged into the page level resource dictionary. In addition, you can also add other ResourceDictionary objects within the MergedDictionaries property-element tags, and other resources outside of those tags.
Important
There can be only one MergedDictionaries property-element tag in a ResourceDictionary, but you can put as many ResourceDictionary objects in there as required.
When merged ResourceDictionary resources share identical x:Key attribute values, .NET MAUI uses the following resource precedence:
The resources local to the resource dictionary.
The resources contained in the resource dictionaries that were merged via the MergedDictionaries collection, in the reverse order they are listed in the MergedDictionaries property.
Tip
Searching resource dictionaries can be a computationally intensive task if an app contains multiple, large resource dictionaries. Therefore, to avoid unnecessary searching, you should ensure that each page in an application only uses resource dictionaries that are appropriate to the page.
Consume a XAML-based resource dictionary from code
Resource dictionaries that are defined in XAML can be consumed in code, provided that the ResourceDictionary is backed by a code-behind file. In Visual Studio, XAML-based ResourceDictionary files that are backed by code-behind files can be added to your project by the .NET MAUI ResourceDictionary (XAML) item template:
XAML-based resource dictionaries that are backed by code-behind files can then be consumed from C# by adding them to the MergedDictionaries collection of the resource dictionary:
You can access resources in a resource dictionary from code like any other dictionary.
The following example shows how to retrieve and apply a resource from a page's resource dictionary:
// Retrieve the Primary color value which is in the page's resource dictionary
var hasValue = Resources.TryGetValue("Primary", out object primaryColor);
if (hasValue)
{
myLabel.TextColor = (Color)primaryColor;
}
This is the recommended approach that ensures that .NET MAUI won't throw a KeyNotFoundException if it's unable to retrieve a resource from code. This can occur when a merged resource dictionary is made up of resources defined in a XAML file, and inline resources. For more information, see GitHub issue #11214.
Note
To retrieve app-wide resources from code, access the App.Current.Resources resource dictionary.
Collaborate with us on GitHub
The source for this content can be found on GitHub, where you can also create and review issues and pull requests. For more information, see our contributor guide.
.NET MAUI feedback
.NET MAUI is an open source project. Select a link to provide feedback:
Learn how to use static and dynamic shared resources to build a MAUI user interface. And see how styles can make the user interface both consistent and accessible.