Avalonia UI遵循MVVM模式点击登录后如何关闭当前登录窗口跳转新窗口
问题原因
MVVM模式下ViewModel层默认不持有View层的实例,所以无法直接调用登录窗口的Close()方法,可通过以下两种方案实现需求:
方案1:事件通知机制(推荐,符合MVVM分离原则)
ViewModel只负责发布登录成功的事件,不直接操作View实例,View层自行订阅事件执行关闭逻辑,完全不会破坏MVVM的分层规则。
- 修改
MainWindowViewModel.cs,添加登录成功事件并在验证通过后触发:
// 新增登录成功事件 public event EventHandler LoginSuccess; public void Login() { Users userDetails = Database.createDB(); // 注意:原代码的&是按位与,要改为逻辑与&& if (Name == userDetails.userName && Password == userDetails.password) { var window1 = new Window1(); window1.Show(); // 触发登录成功事件 LoginSuccess?.Invoke(this, EventArgs.Empty); } else { Text = "Invalid username and password."; } }
- 修改
MainWindow.axaml.cs后台代码,在窗口初始化时订阅事件:
public MainWindow() { InitializeComponent(); var viewModel = new MainWindowViewModel(); DataContext = viewModel; // 登录成功后关闭当前窗口 viewModel.LoginSuccess += (sender, e) => Close(); }
方案2:传递窗口引用(适合小型项目快速实现)
如果项目规模小不需要严格遵守纯MVVM规范,可以直接在构造ViewModel时将当前登录窗口的实例传入,直接调用关闭方法,实现更简单。
- 修改
MainWindowViewModel.cs,新增字段接收窗口引用:
private readonly Window _loginWindow; // 新增带窗口参数的构造函数 public MainWindowViewModel(Window loginWindow) { _loginWindow = loginWindow; } public void Login() { Users userDetails = Database.createDB(); if (Name == userDetails.userName && Password == userDetails.password) { var window1 = new Window1(); window1.Show(); // 直接关闭传入的登录窗口 _loginWindow.Close(); } else { Text = "Invalid username and password."; } }
- 修改
MainWindow.axaml.cs,初始化ViewModel时传入当前窗口实例:
public MainWindow() { InitializeComponent(); DataContext = new MainWindowViewModel(this); }
注意:原有代码中判断条件使用的
&是按位与运算符,建议替换为逻辑与&&,避免不必要的条件执行。
内容的提问来源于stack exchange,提问作者Pamudu
相关产品推荐
相关产品推荐

