0
votes

I've tried searching for this without joy so apologies if I missed it somewhere.

I have 2 projects; ViewModels and Views. Views references ViewModels and serves as the composition root.

I want App.xaml.cs to instantiate MainWindow.xaml in the views project and bind MainWindowViewModel to its' DataContext. So far, so uneventful. The problem happens when MainWindow.xaml uses a static resource from App.xaml.

In App.xaml.cs I have:

public partial class App : Application
{
    private StandardKernel container;

    protected override void OnStartup(StartupEventArgs e)
    {
        this.container = new StandardKernel();
        this.MainWindow = container.Get<MainWindow>();
    }
}

In App.xaml I have:

<Application x:Class="TestApp.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:TestApp">
<Application.Resources>

    <Style x:Key="ButtonStyle" TargetType="Button">
        <Setter Property="Background" Value="Blue"/>
    </Style>
</Application.Resources>

In MainWindow.xaml I have:

<Window x:Class="TestApp.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:TestApp"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Button Style="{StaticResource ButtonStyle}">Test</Button>

When I run the application I get the following error:

Exception: Cannot find resource named 'ButtonStyle'. Resource names are case sensitive.

I'm assuming that because I am manually setting MainWindow in the OnStartup() method the MainWindow class doesn't have its' parent set to App? As a result, the runtime is unable to resolve "{StaticResource ButtonStyle}" on the button.

How do I use an IoC container to construct a View (MainWindow.xaml) that binds to a static resource in App.xaml?

1
It looks like the Application class's Xaml has a different namespace (CompositionRoot.App). I dont know about the DI, but could that be related? - Ryan S
Sorry, I was trying multiple ways to get this working and posted the App.xaml from somewhere else. I've updated the code now. Should be the same namespace. Problem still exists however. - Tom
If you remove the overridden OnStartup method, does it work then? - Ryan S
If I remove it and set the StartupUri to MainWindow.xaml then yes, it works. It only breaks when I try to use an IoC container to resolve MainWindow. - Tom
If StandardKernel creates another AppDomain then Resources will not be there. Check AppDomain.CurrentDomain.IsDefaultAppDomain(), if false, you need to load the resources manually. - user2880486

1 Answers

0
votes

I found a solution that seems to work. First I I registered for the Startup event in App.xaml like so:

<Application x:Class="CompositionRoot.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:TestApp"
             Startup="App_OnStartup">
    <Application.Resources>
        <Style x:Key="ButtonStyle" TargetType="Button">
            <Setter Property="Background" Value="Blue"/>
        </Style>
    </Application.Resources>
</Application>

Then I added the following event handler in App.xaml.cs:

public partial class App : Application
{
    private StandardKernel container;

    private void App_OnStartup(object sender, StartupEventArgs e)
    {
        this.container = new StandardKernel();
        this.MainWindow = container.Get<MainWindow>();
        this.MainWindow.Show();
    }
}

After that MainWindow was able to locate the style in Application.Resource.

Note: overriding OnStartup() in App.xaml.cs doesn't work.