jeff
jeff

Reputation: 3327

Starting app in WPF, how to not use a startup uri, but a window instance

I'm working in a shop that has adopted MVC influences into the WPF\MVVM paradigm. In this realm, the controller is newed up first, which would new it's view and the view model (via MEF).

I'm wondering how to get into the app.xaml.cs to hand it a created window (and it's dependencies) instead of the StartUpUri. I still need global resources to work.

Upvotes: 1

Views: 2191

Answers (3)

Pawulon
Pawulon

Reputation: 77

Just for completeness I will add that you don't even need to start the application in a Application class. You can delete the whole App.xaml and App.xaml.cs and as long as you have a Main method somewhere, the project will compile.

And in case there are more suitable Main methods you can set <StartupObject> in the project's properties.

XXX.cs

using System.Windows;

namespace myNamespace;

public class XXX {

    [STAThread]
    public static int Main() {
        var app = new Application();
        return app.Run(new MainWindow());
    }
}

public class YYY {
    public static int Main() {
        return 0;
    }
}

project.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net8.0-windows</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <UseWPF>true</UseWPF>
        <StartupObject>myNamespace.XXX</StartupObject>
  </PropertyGroup>
    ...
</Project>

Upvotes: 0

Xavier
Xavier

Reputation: 3424

The default project template for WPF applications assumes that you want your main application class to be xaml-based. However, this is not a requirement and you can change it. Doing so allows you to write your own application entry point method and create your own application instance configured the way that you want.

So, you can delete your App.xaml and App.xaml.cs files and create an App.cs file in their place. In that file, do something like this:

internal class App : Application
{
    [STAThread]
    public static int Main(string[] args)
    {
        App app = new App();
        // Setup your application as you want before running it
        return app.Run(new MainWindow());
    }

    public App()
    {
        // (Optional) Load your application resources file (which has a "Page" build action, not "ApplicationDefinition",
        // and a root node of type "ResourceDictionary", not "Application")
        Resources = (ResourceDictionary)Application.LoadComponent(new Uri("/MyAssemblyName;component/Resources.xaml", UriKind.Relative));
    }
}

This allows you specify your main window whichever way you want before running the application. Your application resources file would look something like this:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <!-- Put application resources here -->
</ResourceDictionary>

I always structure my WPF applications this way because it seems simpler and provides more control over how the application is run. (I created a custom WPF application project template in Visual Studio.)

Upvotes: 3

Guilherme
Guilherme

Reputation: 5351

Add the Startup event on the app.xaml file, like that:

<Application x:Class="Test.App" Startup="Application_Startup"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
    <Application.Resources>

    </Application.Resources>
</Application>

And then, in the app.xaml.cs file, handle the event and open the window:

    private void Application_Startup(object sender, StartupEventArgs e)
    {
        Test.MainWindow window = new MainWindow();            
        window.Show();
    }

I don't know if this hurts the MVVM design.

Upvotes: 2

Related Questions