I want to create a Interface to control all windows. I used Microsoft.Extensions.DependencyInjection .
Interface IWindowManager and class WindowManager as:
public interface IWindowManager
{
void OpenWindow<TWindow>() where TWindow : Window;
void CloseWindow<TWindow>() where TWindow : Window;
}
public class WindowManager : IWindowManager
{
private readonly IServiceProvider _serviceProvider;
public WindowManager(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public void OpenWindow<TWindow>() where TWindow : Window
{
var window = _serviceProvider.GetRequiredService<TWindow>();
window.Show();
}
public void CloseWindow<TWindow>() where TWindow : Window
{
var window = _serviceProvider.GetRequiredService<TWindow>();
window.Close();
}
}
In App.xaml.cs, i create IoC container, it's the same as the code of Microsoft Commuinty document https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/ioc
public partial class App : Application
{
public App()
{
Services = ConfigureServices();
}
public new static App Current => (App)Application.Current;
public IServiceProvider Services { get; }
private static IServiceProvider ConfigureServices()
{
var services = new ServiceCollection();
services.AddSingleton<IWindowManager, WindowManager>();
services.AddTransient<MainWindowViewModel>();
services.AddTransient<MainWindow>(
sp => new MainWindow
{ DataContext = sp.GetService<MainWindowViewModel>() });
services.AddTransient<TaskWindowViewModel>();
services.AddTransient<TaskWindow>(
sp => new TaskWindow
{ DataContext = sp.GetService<TaskWindowViewModel>() });
return services.BuildServiceProvider();
}
private void Application_Startup(object sender, StartupEventArgs e)
{
var MW = Services.GetService<MainWindow>();
MW!.Show();
}
}
In MainWindowViewModel.cs, i create two RelayCommand method by CommunityToolkit.Mvvm, and binding with button in Xaml:
public partial class MainWindowViewModel : ObservableObject
{
private readonly IWindowManager _windowManager;
#region Windows Manager
[RelayCommand]
private void OpenTaskWindow()
{
_windowManager.OpenWindow<TaskWindow>();
}
[RelayCommand]
private void CloseMainWindow()
{
_windowManager.CloseWindow<MainWindow>();
}
#endregion
public MainWindowViewModel( IWindowManager windowManager)
{
_windowManager = windowManager;
}
}
I tried the method of OpenTaskWindow workes, but CloseMainWindow does't work. I don't know what's wrong.Please help me, thank you.
I resolved it. Add a dictionary
viewModelWindowMappingto save types of windows and viewModels.Like this, when i want to add another window. I just need add one mapping in
viewModelWindowMapping