2

The following two elements are firing in my implementation of ICommand differently and causing problems. When the implementation enters CanExecuteChanged(object parameter) for the TextBox, the value of parameter is null. When it enters the same method for the Button, the value of parameter is equal to the CommandParameter.

Ideally I'd like in both cases that the CommandParameter value is not sent to the CanExecuteChanged, only to Execute.

Implementation of ICommand

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


        public bool CanExecute(object parameter)
        {
            if (parameter is bool)
            {
                this.canExecute = (bool)parameter;
            }

            return this.canExecute;
        }

        public void Execute(object parameter)
        {
            this.executeAction((T)parameter);
        }              


        internal void RaiseCanExecuteChanged()
        {           
            this.OnCanExecuteChanged();
        }


        private void OnCanExecuteChanged()
        {
            if (this.canExecuteChanged != null)
            {
                this.canExecuteChanged(this, EventArgs.Empty);
            }
        }

TextBox

<TextBox Width="80" Margin="2,2,2,2" Text="{Binding LastName, UpdateSourceTrigger=PropertyChanged}" MaxLength="25">
                <TextBox.InputBindings>
                    <KeyBinding Key="Enter" Command="{Binding SearchCommand}">
                        <KeyBinding.CommandParameter>
                            <s:Boolean>True</s:Boolean>
                        </KeyBinding.CommandParameter>
                    </KeyBinding>
                </TextBox.InputBindings>
            </TextBox>

Button

<Button Margin="2,2,2,2" Padding="10,0,10,0" Content="Search">
                <Button.InputBindings>
                    <MouseBinding Command="{Binding SearchCommand }" MouseAction="LeftClick">
                        <MouseBinding.CommandParameter>
                            <s:Boolean>True</s:Boolean>
                        </MouseBinding.CommandParameter>
                    </MouseBinding>
                </Button.InputBindings>
            </Button>
Kevin
  • 429
  • 3
  • 10

1 Answers1

0

In this case, try the implementation ICommand of @JoshSmith, for me both options worked well:

RelayCommand

public class RelayCommand : ICommand
{
    private readonly Action<object> _execute;
    private readonly Predicate<object> _canExecute;

    public RelayCommand(Action<object> execute)
        : this(execute, null)
    {
    }

    public RelayCommand(Action<object> execute, Predicate<object> canExecute)
    {
        if (execute == null)
        {
            throw new ArgumentNullException("execute");
        }

        _execute = execute;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? true : _canExecute(parameter);
    }

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

        remove
        {
            CommandManager.RequerySuggested -= value;
        }
    }

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

SearchCommand

private RelayCommand _searchCommand = null;

public ICommand SearchCommand
{
    get
    {
        if (_searchCommand == null)
        {
            _searchCommand = new RelayCommand(param => this.Search(param), param => true);
        }

        return _searchCommand;
    }
}

private void Search(object param)
{
    bool parameter = (bool)param;

    if (parameter) 
    {
        MessageBox.Show("Pressed the Enter Key");
    }
}
Anatoliy Nikolaev
  • 22,370
  • 15
  • 69
  • 68
  • First thing Monday morning – Kevin Mar 08 '14 at 08:26
  • Not quite. The command parameter for button still appears to be used in both execute and can execute – Kevin Mar 11 '14 at 15:32
  • @Kevin: So you `do not need` to parameter passed, but then why did you convey? Something I do not quite understand. – Anatoliy Nikolaev Mar 11 '14 at 16:14
  • I need a CommandParameter for the execute statement. My trouble is that I need to set CanExecute to false while the command is running so it cannot be triggered until the execution is complete. In the case of the TextBoxes this works - because when the CanExecute fires from the TextBox's input binding it does not receive the CommandParameter. However when the CanExecute fires from the Button, it does. – Kevin Mar 11 '14 at 16:28
  • @Kevin: Maybe in this case it is easier to set `IsEnabled` to False for Control until the task is executed. In fact it will be the same and easy, I guess. – Anatoliy Nikolaev Mar 11 '14 at 16:38