0
votes

Sorry if this is a stupid question but I cannot seem to work it out, basically I have a button on a window that is to save data. I have added a class of RelayCommand as mentioned here (Top Answer) Binding Button click to a method Everytime I run my project the ICommand SaveCommand Method is hit. From here it created a loop and continously loops. However when the window appears pushing the Save button does not actually cause the ICommand SaveCommand Method to be hit. How can I resolve this? Thanks everyone.

My View:

<av:Button x:Name="btnSave" Content="Save" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="81" Height="44" Margin="52,0,0,20" av:Grid.RowSpan="2" Command ="{Binding SaveCommand}"/>

My ViewModel:

private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    private ICommand _saveCommand;

    public ICommand SaveCommand
    {
        get
        {
            if (_saveCommand == null)
            {
                _saveCommand = new RelayCommand(
                    param => this.SaveObject(),
                    param => this.CanSave()
                    );
            }
            return _saveCommand;
        }
    }

    private bool CanSave()
    {
        // Verify command can be executed here

        return true;
    }

    private void SaveObject()
    {
        // Save command execution logic
    }

RelayCommand Class:

public class RelayCommand : ICommand
{
    #region Fields

    readonly Action<object> _execute;
    readonly Predicate<object> _canExecute;

    #endregion // Fields

    #region Constructors

    /// <summary>
    /// Creates a new command that can always execute.
    /// </summary>
    /// <param name="execute">The execution logic.</param>
    public RelayCommand(Action<object> execute)
        : this(execute, null)
    {
    }

    /// <summary>
    /// Creates a new command.
    /// </summary>
    /// <param name="execute">The execution logic.</param>
    /// <param name="canExecute">The execution status logic.</param>
    public RelayCommand(Action<object> execute, Predicate<object> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");

        _execute = execute;
        _canExecute = canExecute;
    }

    #endregion // Constructors

    #region ICommand Members

    [DebuggerStepThrough]
    public bool CanExecute(object parameters)
    {
        return _canExecute == null ? true : _canExecute(parameters);
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public void Execute(object parameters)
    {
        _execute(parameters);
    }

    #endregion // ICommand Members
}
2
is the datacontext of the view set up to be equal to the view model?User1
Yes the DataContext is set to be this ViewModel @user1David B
Any code in your window/Viewmodel's constructor?Bolu
also should be if(PropertyChanged != null)Xi Sigma
repeatable execute CanSave() is fine, as it needs to be evaluated to disable/enable the button.Bolu

2 Answers

3
votes

You made a mistake/typo in SaveCommand's get section, you should change

if (_saveCommand != null) to if (_saveCommand == null)

0
votes

Your CanSave method return false.

Consider resolving that.