rosi97
rosi97

Reputation: 245

WPF Static resource cannot be found

I want to create a WPF .NET Core 3.1 app using MvvmLight.

Following this tutorial I'm now stuck with an error while building.
The static resource of my ViewModelLoactor cannot be resolved while creating the main window but I cannot seem to find any differences between the tutorial source code and mine.

When I set a breakpoint at window.Show() in my app.xaml.cs it looks like the mainwindow will be initialized before it hits the breakpoint.

MainWindow.xaml

<Window x:Class="openManufacture.WPF.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:openManufacture.WPF" 
    xmlns:vm="clr-namespace:openManufacture.WPF.ViewModel"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800"
    DataContext="{Binding Source={StaticResource Locator}, Path=MainViewModel}">

<Grid>

</Grid>

App.xaml.cs

using System;
using System.Windows;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using openManufacture.WPF.ViewModel;

namespace openManufacture.WPF
{
public partial class App : Application
{
    private readonly IHost host;
    public static IServiceProvider ServiceProvider { get; private set; }

    public App()
    {
        host = Host.CreateDefaultBuilder()  
                .ConfigureAppConfiguration((context, builder) =>
                {
                    builder.AddJsonFile("appsettings.local.json", optional: true);
                }).ConfigureServices((context, services) =>
                {
                    ConfigureServices(context.Configuration, services);
                })
                .Build();

        ServiceProvider = host.Services;
    }
    private void ConfigureServices(IConfiguration configuration,
        IServiceCollection services)
    {
        services.Configure<AppSettings>(configuration.GetSection(nameof(AppSettings)));

        services.AddSingleton<MainViewModel>();
        services.AddTransient<MainWindow>();
    }

    protected override async void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        await host.StartAsync();
        var window = ServiceProvider.GetRequiredService<MainWindow>();
        window.Show();
    }
    protected override async void OnExit(ExitEventArgs e)
    {
        using (host)
        {
            await host.StopAsync(TimeSpan.FromSeconds(5));
        }
        base.OnExit(e);
    }
}


} 

App.xaml

<Application x:Class="openManufacture.WPF.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:openManufacture.WPF"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         mc:Ignorable="d">

<Application.Resources>
    <ResourceDictionary>
        <vm:ViewModelLocator
            xmlns:vm="clr-namespace:openManufacture.WPF.ViewModel"
            x:Key="Locator"
            d:IsDataSource="True"/>
    </ResourceDictionary>
</Application.Resources>
</Application>

ViewModelLocator.cs

using Microsoft.Extensions.DependencyInjection;

namespace openManufacture.WPF.ViewModel
{
public class ViewModelLocator
{
    public MainViewModel MainViewModel => 
App.ServiceProvider.GetRequiredService<MainViewModel>();

}
}

Upvotes: 0

Views: 1823

Answers (1)

Daliran
Daliran

Reputation: 46

The ViewModelLocator cannot be resolved because (maybe I'm wrong) there is a bug in how the resource dictionaries are handled in WPF Core.

To make it work you need to add at least two resources into the app dictionary.

<Application.Resources>
    <ResourceDictionary>
        <vm:ViewModelLocator
            xmlns:vm="clr-namespace:WpfNetCoreMvvm.ViewModels"
            x:Key="Locator"
            d:IsDataSource="True" />

        <Style TargetType="Window">
            <Setter Property="FontSize" Value="28" />
        </Style>
    </ResourceDictionary>
</Application.Resources>

The author of the tutorial probably forgot to update the code snippets but, if you download the source code, you can see that there are in fact two resources in his dictionary.

Upvotes: 3

Related Questions