Home > other >  Open Main Window in WPF MVVM
Open Main Window in WPF MVVM

Time:10-22

I am new to WPF and am building a WPF MVVM application.

I can't seem to figure out how to open the main window in my app.

App.xaml

<Application
    x:Class="First.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    DispatcherUnhandledException="OnDispatcherUnhandledException"
    Startup="OnStartup" />

App.xaml.cs

private async void OnStartup(object sender, StartupEventArgs e)
{
    var appLocation = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

    //configure host

    await _host.StartAsync();
}

I need to add MainView as the main window.

MainView.xaml.cs

public MainView(MainViewModel viewModel)
{
    InitializeComponent();
    DataContext = viewModel;
}

Since I have a parameterized constructor, injecting the ViewModel (via dependency injection) and setting the DataContext to it, I can't simply add

MainView mainView = new MainView();
MainView.Show();

in the OnStartUp method in App.xaml.cs, as it needs a parameter.

What is the best approach to open the window?

I have tried using StartupUri="MainView.xaml" in App.xaml, but I need the OnStartup method to configure the services and so on.

CodePudding user response:

You should try again to understand dependency injection I guess. Also when using an IoC container you also want to apply the Dependency Inversion principle. Otherwise dependency injection is very useless and only overcomplicates your code.

You must retrieve the composed instance from the IoC container. In your case, it seems you are using the .NET Core dependency injection framework. In general, the pattern is the same for every IoC framework: 1) register dependencies 2) compose the dependency graph 3) get the startup view from the container and show it 4) dispose the container (handle lifecycle - don't pass it around!):

App.xaml.cs

private async void OnStartup(object sender, StartupEventArgs e)
{
  var services = new ServiceCollection();
  services.AddSingleton<MainViewModel>();
  services.AddSingleton<MainView>();
  await using ServiceProvider container = services.BuildServiceProvider();

  // Let the container compose and export the MainView
  var mainWindow = container.GetService<MainView>();

  // Launch the main view
  mainWindow.Show();
}
  • Related