1

I want to create a special class of Command (I've called it DropDownRelayCommand, which are to be used on a dropdown button which has a content which consists of buttons with command.

The idea is that the dropdown button should be disabled (or possibly collapsed) if no buttons in it's content are enabled. I want to create a general solution.

I have been unable to do this in XAML (in a general way, anyway).

I want this DropDownRelayCommand to have it's own CanExecute methods, which should be examiing all CanExecute of its containing commands. The problem is this error (on the marked argument in the code below) : An object reference is required for the non-static field, method, or property 'Js.Mvvm.DropDownRelayCommand.CanDropDownExecute(T)'. I cannot use "this" because that is not allowed in a constructor.

Here's my code (I am aware that the containing commands will propably be recieving canexecute request, making this a bit ineffective. But typically I would have only a handful commands so performance is propably not so important:

public class DropDownRelayCommand<T> : RelayCommand<T>
{
    private readonly List<RelayCommand<T>> _commands = new List<RelayCommand<T>>();
    private bool _hasAnyCanExecute;


    #region Constructors
    public DropDownRelayCommand(Action<T> execute, params RelayCommand<T>[] commands)
        : base(execute, **CanDropDownExecute**)
    {
        AddCommandRange(commands);
    }

    public bool CanDropDownExecute(T argument)
    {
       _hasAnyCanExecute = false;
        foreach (RelayCommand<T> command in _commands)
        {
            _hasAnyCanExecute = _hasAnyCanExecute || command.CanExecute(argument);
        }
        return _hasAnyCanExecute;
    }

    #endregion


    #region Public Methods

    public void AddCommandRange(params RelayCommand<T>[] commands)
    {
        if (commands == null) return;
        foreach (RelayCommand<T> command in commands)
        {
            _commands.Add(command);
        }
    }


    public void RemoveCommandRange(params RelayCommand<T>[] commands)
    {
        if (commands == null) return;
        foreach (RelayCommand<T> command in commands)
        {
            if (_commands.Contains(command))
            {
                _commands.Remove(command);
            }
        }
    }

    #endregion

}
iakob
  • 309
  • 1
  • 6
  • Are you sure you *need* to derive your command from `RelayCommand` here? (What `RelayCommand` are we talking about, anyway? [`RelayCommand` is not an official class from the BCL.](http://stackoverflow.com/questions/862570/how-can-i-use-the-relaycommand-in-wpf)) The point of my inquiry is to find out why you need to pass the `CanExecute` logic as a delegate rather than just override the inherited method. – O. R. Mapper Dec 06 '13 at 08:54
  • RelayCommand is not designed to be used like this, it is meant to give you access to Commands through delegates. I think you should just create a class implementing ICommand. – Iain Dec 06 '13 at 09:00

0 Answers0