You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Avalonia UI遵循MVVM模式点击登录后如何关闭当前登录窗口跳转新窗口

问题原因

MVVM模式下ViewModel层默认不持有View层的实例,所以无法直接调用登录窗口的Close()方法,可通过以下两种方案实现需求:


方案1:事件通知机制(推荐,符合MVVM分离原则)

ViewModel只负责发布登录成功的事件,不直接操作View实例,View层自行订阅事件执行关闭逻辑,完全不会破坏MVVM的分层规则。

  1. 修改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.";
    }
}
  1. 修改MainWindow.axaml.cs后台代码,在窗口初始化时订阅事件:
public MainWindow()
{
    InitializeComponent();
    var viewModel = new MainWindowViewModel();
    DataContext = viewModel;
    // 登录成功后关闭当前窗口
    viewModel.LoginSuccess += (sender, e) => Close();
}

方案2:传递窗口引用(适合小型项目快速实现)

如果项目规模小不需要严格遵守纯MVVM规范,可以直接在构造ViewModel时将当前登录窗口的实例传入,直接调用关闭方法,实现更简单。

  1. 修改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.";
    }
}
  1. 修改MainWindow.axaml.cs,初始化ViewModel时传入当前窗口实例:
public MainWindow()
{
    InitializeComponent();
    DataContext = new MainWindowViewModel(this);
}

注意:原有代码中判断条件使用的&是按位与运算符,建议替换为逻辑与&&,避免不必要的条件执行。

内容的提问来源于stack exchange,提问作者Pamudu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 01:24:00