我想创建一个界面来控制所有窗口。我用Microsoft.Extensions.DependencyInjection
。
接口IWindowManager和类WindowManager为:
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();
}
}
在App.xaml.cs中,我创建了IoC容器,它与Microsoft Commuinty文档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();
}
}
在MainWindowViewModel.cs中,我通过CommunityToolkit.Mvvm创建了两个RelayCommand方法,并与Xaml中的button绑定:
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;
}
}
我尝试了OpenTaskWindow的方法,但CloseMainWindow不起作用。我不知道怎么了。请帮帮我,谢谢。
4条答案
按热度按时间qoefvg9y1#
当你想用WindowManager打开一个窗口时
1.您从DI-Container
获取一个新窗口示例
1.您将显示新窗口示例
当你想用WindowManager关闭一个窗口时
1.从DI-Container
中获取一个新窗口示例
1.关闭新窗口示例
这就是错的地方:你总是创建一个新的示例-因为窗口注册为transient-当你想关闭一个已经显示的窗口时关闭它。
kgsdhlau2#
我解决了。添加一个字典
viewModelWindowMapping
来保存windows和viewModels的类型。就像这样,当我想添加另一个窗口。我只需要在
viewModelWindowMapping
中添加一个Map5jvtdoz23#
应关闭以前打开的窗口示例。
例如,您可以在
WindowManager
类中处理此问题,方法是跟踪集合中当前打开的窗口,例如:ebdffaop4#
我想重写MainWindow类中的
CloseWindow
方法。并且按钮是在MainWindowViewModel类中点击的。
它可以工作,但不是我想要的。这意味着我将覆盖每个视图中的
CloseWindow
方法。我的意图是通过一个界面控制所有窗口的打开或关闭。