Post­Sharp Documentation / XAML / Command

Command

In the GUI applications built using MVVM pattern, it's common for the view model class to define commands that can be performed by the user in the associated XAML view. These commands are implemented as nested classes of the view model classes, and require a lot of boilerplate code.

The CommandAttribute aspect allows you to implement commands in your view model classes without adding nested classes, with greatly reduces boilerplate code. The aspect also integrates with the NotifyPropertyChangedAttribute aspect, which makes it much easier to implement the CanExecute logic.

This topic contains the following sections:

Creating a simple command

To add a command named LoadContactsList to your view model class

  1. Implement the command logic in the ExecuteLoadContactsList method in your view model class. This method will be the equivalent to the ICommand.Execute(Object) method.

    Optionally, the Execute method can have one parameter of any type, which becomes the command parameter.

  2. Add a LoadContactsListCommand property to your view model class and mark it with the CommandAttribute attribute. The property must be of type ICommand and have both a getter and a setter.

Example

The following code snippet defines a dependency property named LoadContactsList.

C#
[Command]
public ICommand LoadContactsListCommand { get; private set; }

public void ExecuteLoadContactsList()
{
    // ...
}

After adding a new command to your view model class you can bind it to a UI control in your XAML code.

XAML
<Button x:Name="LoadButton" Content="Load contacts" Command="{Binding LoadContactsListCommand}"
  HorizontalAlignment="Left" Margin="361,10,0,0" VerticalAlignment="Top" Width="85" Height="20"/>
Determining whether your command can be executed

The UI controls in the GUI application can be enabled or disabled based on what actions are available to the user in the current state of the application. This feature is usually implemented by the ICommand.CanExecute(Object) method.

The CommandAttribute aspect provides a clean way to determine the availability of the actions. For each command in your view model class, you can implement a CanExecute property or method that validates whether this command can be currently executed.

Adding a CanExecute property

To allow the view to determine the availability of the CreateContact command, simply add a public bool property named CanExecuteCreateContact to the same class.

C#
[Command]
public ICommand CreateContactCommand { get; private set; }

public bool CanExecuteCreateContact
{
    get
    {
        bool canCreateContact = true;
        // ...
        return canCreateContact;
    }
}

public void ExecuteCreateContact()
{
    // ...
}

The CanExecute properties associated with the commands support the NotifyPropertyChangedAttribute aspect. Therefore, if you add the NotifyPropertyChangedAttribute aspect to the view model class, the UI will be notified of changes in the CanExecute properties.

Adding a CanExecute method

A limitation of the CanExecute is that they cannot depend on the input argument of the command. For example, with the DeleteContact command, you may want to validate whether the current user has the permission to delete the currently selected contact. If your availability logic depends on the input argument, you must use a CanExecute method instead of a property.

To allow the UI to determine the availability of the DeleteContact command, add a CanExecuteDeleteContact method to the view model class. The method must have one parameter and return a bool value. The parameter type must be assignable from the type of the command's input argument.

C#
[Command]
public ICommand DeleteContactCommand { get; private set; }

public bool CanExecuteDeleteContact(int contactId)
{
    bool canDeleteContact = true;
    // ...
    return canDeleteContact;
}

public void ExecuteDeleteContact(int contactId)
{
    // ...
}
Overriding naming conventions

The CommandAttribute aspect follows a predefined naming convention when looking for methods and properties associated with the command in your view model class. You can override the naming convention and choose your own member names by setting properties on the CommandAttribute. The following table shows the default naming convention and the properties used to override member names.

Command pattern's naming conventions

Member kind

Default name

Example

Override property

Command property

CommandName -or- CommandNameCommand

UpdateContact -or- UpdateContactCommand

N/A

Execute method

ExecuteCommandName

ExecuteUpdateContact

ExecuteMethod

CanExecute method

CanExecuteCommandName

CanExecuteUpdateContact

CanExecuteMethod

CanExecute property

CanExecuteCommandName

CanExecuteUpdateContact

CanExecuteProperty

The following examples shows a command that does not respect naming conventions.

C#
[Command(ExecuteMethod = nameof(UpdateContact), CanExecuteMethod = nameof(CanUpdate))]
public ICommand UpdateContactCommand { get; private set; }

public bool CanUpdate(object newData)
{
    bool canUpdate = true;
    // ...
    return canUpdate;
}

public void UpdateContact(object newData)
{
    // ...
}
See Also