Phuluso Ramulifho
Phuluso Ramulifho

Reputation: 498

.NET MAUI StaticResource not found for key

When I inject the mainpage to the App class constructor I am getting StaticResource not found for key But if I don't inject the Mainpage on the App constructor it works.

I have a global resource Theme file which I call on the App.xaml.cs where i declare the static resource:

 <Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Resources/Styles/Colors.xaml" />
            <ResourceDictionary Source="Themes/LightTheme.xaml" /> <!--Theme file-->
            <ResourceDictionary Source="Themes/DarkTheme.xaml" /> <!--Theme file-->
            <ResourceDictionary Source="Resources/Styles/Styles.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

This is my App.cs file:

public App(MainPage mainPage)
{

    InitializeComponent();

    MainPage = mainPage;

}

The following code is in the MainPage.xaml:

    <StackLayout BackgroundColor="{StaticResource SecondaryBackroundColor}" Grid.Row="0">
        <Image 
            Source="ic_logo.png"
            SemanticProperties.Description="Cute dot net bot waving hi to you!"
            HeightRequest="200"
            HorizontalOptions="Center"  VerticalOptions="CenterAndExpand"/>

    </StackLayout>

I have added the MainPage to the mauiprogram.cs class

builder.Services.AddTransient<MainPage>();

Upvotes: 9

Views: 9607

Answers (4)

thomasgalliker
thomasgalliker

Reputation: 1887

We cannot inject the "MainPage" into App ctor if MainPage uses static resources from App.xaml (or further references xamls, e.g. Styles.xaml or Colors.xaml). The instance of MainPage is created by DI just before it is injected into App.xaml.cs' constructor. We need to run App.xaml.cs' InitializeComponent() method before we can run MainPage's InitializeComponent() method.

public partial class App : Application
{
    public App(IServiceProvider serviceProvider)
    {
        this.InitializeComponent();

        var mainPage = serviceProvider.GetRequiredService<MainPage>();
        this.MainPage = new NavigationPage(mainPage);
    }
}

Don't use DynamicResource unless really necessary (e.g. when runtime updates of resources is required).

Upvotes: 4

Stonehead
Stonehead

Reputation: 376

I had the same problem and what helped as a workaround is to use DI for all pages except the first/main one. That one got new'd in App.xaml.cs.

 public partial class App : Application
{
    //public App(MainPage mainPage)
    public App(IServiceProvider serviceProvider)
    {
        InitializeComponent();
        MainPage = new NavigationPage(new MainPage(serviceProvider.GetRequiredService<MainPageViewModel>()));
    }
}

Upvotes: 1

user22144434
user22144434

Reputation: 1

For this error using .NET 7 I modified my code like this:

<!-- In App.xaml -->
<?xml version = "1.0" encoding = "UTF-8" ?>
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
              xmlns:local="clr-namespace:StylesDemo"
              x:Class="StylesDemo.App">
    <Application.Resources>

        <ResourceDictionary>

            <!--APP-level styles-->
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resources/Styles/Colors.xaml" />
                <ResourceDictionary Source="Resources/Styles/Styles.xaml" />
            </ResourceDictionary.MergedDictionaries>


            <!--Example of creating Global Styles globalButtonstyle in App.xaml-->
            <Color x:Key="backGroundColorButtonGlobal">#440055</Color>
            <Color x:Key="textColorButtonGlobal">#FFFFFF</Color>

            <Style TargetType="Button" x:Key="GlobalButtonstyle">
                <Setter Property="TextColor" Value="{StaticResource textColorButtonGlobal}" />
                <Setter Property="BackgroundColor" Value="{StaticResource backGroundColorButtonGlobal}" />
                <Setter Property="FontAttributes" Value="Bold" />
                <Setter Property="FontSize" Value="Micro" />
            </Style>
        </ResourceDictionary>

    </Application.Resources>
</Application>



<!-- In MainPage.xaml -->
<Button Text="Global Style" Style="{StaticResource globalButtonStyle}"/>
<Button Text="Global Style" Style="{DynamicResource globalButtonStyle}"/>

Upvotes: 0

Liyun Zhang - MSFT
Liyun Zhang - MSFT

Reputation: 14434

I have created a new project to test your code and met the same error. Then I added two break point. One is on the MainPage's construction method and the other is on the App.cs's construction method.

I found that the mainpage's construction method excute before the app.cs' when I used builder.Services.AddTransient<MainPage>();. So the error appeared.

Finally, you can follow up this issue about Can't use App.xaml resources after Dependency Injection .NET MAUI on the github. Or just use the DynamicResource instead of the StaticResource such as:

 <StackLayout BackgroundColor="{DynamicResource SecondaryBackroundColor}"

I have tried it. Using the DynamicResource works.

Upvotes: 8

Related Questions