Search code examples
c#wpfmvvmicommand

Why wpf controls have only one command? (MVVM)


The question is why wpf controls have only one command?

I have this question because I'm creating custom control. I have two events. To make a binding to viewmodel ICommand property I need to use <i:Interaction.Triggers>. As I think I can create several commands and one who will use my control will have a choice use event for code behind or use these commands for mvvm. In that case no one will have a need to use <i:Interaction.Triggers>.

But as I know all standard controls have only one command. And I can't understand and find answer why controls have only one command? Why it is a good pattern and why it is bad to have more than one command in control?


Solution

  • The question is why wpf controls have only one command?

    There is no rule that a control must be limited to a single command. It's true that buttons, by way of ICommandSource, expose only a single command. It makes sense for most controls, which are relatively simple and have a single responsibility. However, complex controls can certainly define more than one.

    Slider, for instance, declares and handles several commands:

    public static RoutedCommand IncreaseLarge { get; }
    public static RoutedCommand DecreaseLarge { get; }
    public static RoutedCommand IncreaseSmall { get; }
    public static RoutedCommand DecreaseSmall { get; }
    public static RoutedCommand MinimizeValue { get; }
    public static RoutedCommand MaximizeValue { get; }
    

    Granted, Slider does not expose these commands via instance-level properties, as there is little reason to allow them to be overridden. They are all handled by the slider itself, and they all do the same thing: they change the current value of the slider. The user only expects something to happen when the value changes; how it changes it not terribly relevant. The important information can generally be communicated via a single ValueChanged event.

    I cannot, off the top of my head, think of a stock WPF control that does allow more than one command to be assigned to each instance. That said, I can easily conceive of such a control. Consider, for example, a 'spinner' control with up and down buttons. While the up/down buttons on a spinner could be used to manipulate a single scalar value like the slider, you might decide to use it in an entirely different way. For example, you might want the up/down buttons to function like elevator call buttons. If the spinner exposes a separate UpCommand and DownCommand, you retain the flexibility necessary to accommodate both scenarios.

    If you have a custom control, and you feel it is appropriate to define more than one command, then go right ahead.

    Continuous Command Invocation with RepeatButton

    You mentioned this use case in one of your comments:

    I need to do some continuous action while button is in down state

    WPF ships with a RepeatButton control for precisely this purpose. You've already seen it used for the arrow buttons in the default ScrollBar template. Just bind the Command to whatever action you want to repeat while the button is held in its pressed state:

    <RepeatButton Content="Hold to Repeat Command"
                  Command="{Binding YourRepetitiveCommand}" />