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();
}