Reputation: 610
In order to familiarize myself with MVVM for WinRT I have been looking at the example MvvmLight WinRT project. Currently I'm running into an issue where my RelayCommand is only called once (on construction of viewmodel). What I want to do is go to the MainViewModel if the user is authorized. If I remove the conditional check of the login in the LoginCommand method, the RelayCommand works as expected. Any thoughts as to what I'm doing wrong? Should I not being doing my validation within the LoginCommand?
LoginViewModel (some code has been removed):
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 (some code has been removed):
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 (some code has been removed)
<Button Content="Login"
x:Name="NextPageButton"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Margin="10"
Command="{Binding LoginCommand}" />
Upvotes: 1
Views: 150
Reputation: 5904
The problem is the condition. When your LoginPage
loads, it tries to bind your Button
to the LoginCommand
. In order to achieve that, it gets the LoginCommand
from your ViewModel
. At that point in time Login
is null and therefore the property will return _navigateCommand
which is null
. After that the page will not try to use the LoginCommand
because it already knows its value.
To solve this you could move the condition inside the lambda expression:
public RelayCommand LoginCommand
{
get
{
return _navigateCommand ?? (_navigateCommand = new RelayCommand(
() =>
{
if (login != null && login.UserName.Equals("Test"))
{
_navigationService.Navigate(typeof(MainPage));
}
}));
}
}
An even better solution would be to move the authorization to another class. Something like:
public RelayCommand LoginCommand
{
get
{
return _navigateCommand ?? (_navigateCommand = new RelayCommand(
() =>
{
if (_authorizationService.UserAuthorized(login))
{
_navigationService.Navigate(typeof(MainPage));
}
}));
}
}
Hope this helps.
Upvotes: 1