light
light

Reputation: 816

MVVM light command not firing

I have a simple login form that I am trying to get working, but for some reason the login button does not call the LoginCommand and I can't figure out why, can someone help me...

Here is the code for the form:

<Window x:Class="App.Views.Login"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Login" Height="200" Width="340"
    DataContext="{Binding Login, Source={StaticResource Locator}}" ResizeMode="NoResize">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="10"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="10"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Label Content="Username:" HorizontalAlignment="Right" VerticalAlignment="Top" Grid.Row="1" Grid.Column="1" Padding="0,1,5,0"/>
    <Label Content="Password:" HorizontalAlignment="Right" VerticalAlignment="Top" Padding="0,1,5,0" Grid.Row="3" Grid.Column="1"/>
    <TextBox HorizontalAlignment="Left" VerticalAlignment="Top" Width="200" Height="20" Grid.Row="1" Grid.Column="2" Text="{Binding UserName}"/>
    <PasswordBox x:Name="password" HorizontalAlignment="Left" VerticalAlignment="Top" Width="200" Height="20" Grid.Row="3" Grid.Column="2"/>
    <Button Command="{Binding Source=LoginCommand}" CommandParameter="{Binding ElementName=password}" Content="Login" Grid.Row="5" Grid.ColumnSpan="2" Grid.Column="1" HorizontalAlignment="Center" Width="60"/>
</Grid>
</Window>

Here is my LoginViewModel:

using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System;
using System.Net.Http;
using System.Windows.Controls;
using System.Windows.Input;

namespace App.ViewModels
{
public class LoginViewModel : ViewModelBase
{
    public Login LoginModel;

    public ICommand LoginCommand;

    public ICommand RegisterViewCommand;

    public ICommand ExitViewCommand;

    public LoginViewModel()
    {
        LoginModel = new Models.Login();
        LoginCommand = new RelayCommand<object>(p => Login(p));
        RegisterViewCommand = new RelayCommand(() => Register());
        ExitViewCommand = ApplicationCommands.Close;
    }

    public string UserName
    {
        get
        {
            return LoginModel.UserName;
        }
        set
        {
            if(value != LoginModel.UserName)
            {
                LoginModel.UserName = value;
                RaisePropertyChanged("UserName");
            }
        }
    }

    #region Private Helpers

    private void Register()
    {
        throw new NotImplementedException();
    }

    private async void Login(object parameter)
    {
        var passwordBox = parameter as PasswordBox;
        LoginModel.Password = passwordBox.Password;
        LoginModel.RememberMe = true;
        var response = await HttpClientSingleton.Instance.PostAsJsonAsync("http://localhost:52841/Account/ClientLogin", LoginModel);
        bool success;
        if (bool.TryParse(await response.Content.ReadAsStringAsync(), out success))
        {
        }
    }

    #endregion Private Helpers
}
}

I put a breakpoint at the first line of the Login method and it never actually hits it. I have also changed the UserName property to return a pre-defined string to test the DataContext binding and the UserName textbox displays this pre-defined string so I'm pretty sure the form is being bound properly. Any suggestions?

Upvotes: 0

Views: 649

Answers (1)

Peter Hansen
Peter Hansen

Reputation: 8907

I think your problem is that you are binding to a public field instead of a property.

You can see the kind of things that can be used as binding-sources here on MSDN. Fields it not one of them.

So exposing the command as a property instead should work:

public ICommand LoginCommand { get; private set; }

Upvotes: 3

Related Questions