Ramblings of General Geekery

Writing a custom Main() method for WPF applications

Creating a new WPF project in Visual Studio gives you the following pretty simple application markup and code:

<Application x:Class="WpfApplication2.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    StartupUri="Window1.xaml">
</Application>
namespace WpfApplication2
{
    public partial class App : Application
    {
    }
}

Understanding how it really works, and how to supply your own custom Main() method, is just a search query away. You basically need to change the application’s build action from “Application Definition” to “Page”, create a constructor that calls “InitializeComponent”, and write your Main() by eventually calling one of the application’s “Run” method overloads.

namespace WpfApplication1
{
    public partial class App : Application
    {
        App()
        {
            InitializeComponent();
        }

        [STAThread]
        static void Main()
        {
            Window1 window = new Window1();
            App app = new App();
            app.Run(window);
        }
    }
}

Don’t forget, also, to remove the “StartupUri” from the App.xaml, otherwise another copy of window will show up (unless you get an error because the URI points to a non existing XAML resource).

What most articles won’t tell you, though (some of them actually getting it wrong), is that it’s important that you create the application before you create your first window. To illustrate this, let’s add an application resource to App.xaml:

<Application 
    x:Class="WpfApplication1.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Application.Resources>
        <Style TargetType="Button">
            <Setter Property="Background" Value="Red" />
        </Style>
    </Application.Resources>
</Application>

It’s a style that makes buttons red. Since it’s defined at application level, all buttons in all the windows should be red (except those that define their own local style override). For example, here’s the markup for my Window1:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <Button>Is This Red?</Button>
    </Grid>
</Window>

We should see a window with a red button in it. But when I run the project, I get this:

Well… it’s not red.

The issue is that the window is created before the application. This means that when it queries the current application to get the globals resources, it finds nothing. What you need to do is simply create the application first:

[STAThread]
static void Main()
{
    App app = new App();
    Window1 window = new Window1();
    app.Run(window);
}

By simply switching those two lines, you get the expected result:

This drove me crazy for an hour or so – I thought there was something funky going on with my theme management code or something. Hopefully this will save someone some pain.