c# - NavigateCommand 只调用一次

标签 c# wpf mvvm windows-store-apps mvvm-light

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

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加载时,它会尝试绑定(bind)您的 ButtonLoginCommand .为了实现这一点,它得到 LoginCommand来自您的ViewModel .在那个时间点Login为空,因此该属性将返回 _navigateCommand这是null .之后页面将不会尝试使用 LoginCommand因为它已经知道它的值(value)。

为了解决这个问题,您可以在 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));
                }
            }));
    }
}

希望这可以帮助。

关于c# - NavigateCommand 只调用一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22795779/

相关文章:

c# - MVVM - 参数行为或查找特定父/用户控件资源

c# - 使用子 ViewModel 创建 ViewModel

c# - 在 SQL 中存储 bool 值?

c# - 将 Excel 保存为管道分隔的 CSV(XlFileFormat 枚举)

wpf - MVVM Light DispatcherHelper 和带 MSTest 的单元测试

c# - WPF、MVVM中U盘检测放哪里

WPF MVVM 将数据网格列动态绑定(bind)到集合

c# - System.Runtime.InteropServices.COMException (0x80040154)

c# - 获取文件夹 ID C#

c# - KeyEventArgs.Key 到 char