导航命令只调用一次

本文关键字:一次 命令 调用 导航 | 更新日期: 2023-09-27 17:55:51

为了熟悉 MVVM for WinRT,我一直在查看示例 MvvmLight WinRT 项目。目前我遇到了一个问题,我的 RelayCommand 只被调用一次(在构建视图模型时)。我想做的是,如果用户获得授权,则转到 MainViewModel。如果我在 LoginCommand 方法中删除登录的条件检查,则 RelayCommand 将按预期工作。关于我做错了什么有什么想法吗?我不应该在登录命令中进行验证吗?

LoginViewModel(某些代码已被删除):

public class LoginViewModel : ViewModelBase {
  private readonly IDataService _dataService;
  private readonly INavigationService _navigationService;
  private RelayCommand _navigateCommand;
  private Login login; //contains username and password
  /// <summary>
  /// Gets the NavigateCommand.
  /// THIS DOES NOT GET FIRED UPON BUTTON CLICK
  /// </summary>
  public RelayCommand LoginCommand{
     get {
        if (login != null && login.UserName.Equals("Test"))
           return _navigateCommand ?? (_navigateCommand = new RelayCommand(() => _navigationService.Navigate(typeof(MainPage))));
        return _navigateCommand;
     }
  }

LoginPage.xaml.cs(某些代码已被删除):

public sealed partial class LoginPage {
  public LoginViewModel Vm {
     get { return (LoginViewModel)DataContext; }
  }
  public LoginPage() {
     InitializeComponent();
  }
  protected override void LoadState(object state) {
     var casted = state as LoginPageState;
     if (casted != null) {
        Vm.Load(casted);
     }
  }
  protected override object SaveState() {
     return new LoginPageState {
        Credentials = new Login {
           UserName = txtUserName.Text,
           Password = txtPassword.Text
        }
     };
  }
  public class LoginPageState {
      public Login Credentials { get; set; }
      }
  }
}

LoginPage.xaml(某些代码已被删除)

<Button Content="Login"
            x:Name="NextPageButton"
            HorizontalAlignment="Right"
            VerticalAlignment="Top"
            Margin="10"
            Command="{Binding LoginCommand}" />

导航命令只调用一次

问题是条件。加载LoginPage时,它会尝试将您的Button绑定到LoginCommand。为了实现这一目标,它从您的ViewModel中获得LoginCommand。在该时间点,Login为 null,因此该属性将返回_navigateCommandnull。之后,页面将不会尝试使用该LoginCommand,因为它已经知道其值。

要解决此问题,您可以将条件移动到 lambda 表达式中:

public RelayCommand LoginCommand
{
    get
    {
        return _navigateCommand ?? (_navigateCommand = new RelayCommand(
            () =>
            {
                if (login != null && login.UserName.Equals("Test"))
                {
                    _navigationService.Navigate(typeof(MainPage));
                }
            }));
    }
}

更好的解决方案是将授权移动到另一个类。 像这样:

public RelayCommand LoginCommand
{
    get
    {
        return _navigateCommand ?? (_navigateCommand = new RelayCommand(
            () =>
            {
                if (_authorizationService.UserAuthorized(login))
                {
                    _navigationService.Navigate(typeof(MainPage));
                }
            }));
    }
}

希望这有帮助。