docs.unity3d.com
Search Results for

    Show / Hide Table of Contents

    Commanding

    In the Model-View-ViewModel (MVVM) architectural pattern, commanding plays a crucial role in handling user interactions and controlling the flow of commands between different components of the application. This documentation page explores the commanding patterns in MVVM using App UI.

    For a more detailed example of how to use commanding in App UI, see the MVVM & Redux Sample.

    Introduction

    Commanding in MVVM refers to the mechanism of connecting user interface elements (usually buttons, menu items, etc.) with actions in the ViewModel. This separation allows for better testability, maintainability, and flexibility in handling user inputs.

    In App UI, like most other MVVM frameworks, commanding is implemented using the ICommand interface provided by the System.Windows.Input namespace. The ICommand interface defines two methods: CanExecute and Execute.

    Commands

    RelayCommand

    The RelayCommand class is a simple implementation of the ICommand interface.

    You can create a RelayCommand instance by passing a delegate to the constructor. The delegate will be invoked when the command is executed. Optionally, you can also pass a delegate to the constructor to determine whether the command can be executed.

    public class MyViewModel : ObservableObject
    {
        public RelayCommand MyCommand { get; }
        
        public MyViewModel()
        {
            MyCommand = new RelayCommand(ExecuteMyCommand, CanExecuteMyCommand);
        }
    
        private void ExecuteMyCommand()
        {
            // Do something
        }
    
        private bool CanExecuteMyCommand()
        {
            // Return true or false depending on whether the command can be executed
        }
    }
    

    You can also use the generic version of RelayCommand to pass a parameter to the command delegate.

    public class MyViewModel : ObservableObject
    {
        public RelayCommand<string> MyCommand { get; }
        
        public MyViewModel()
        {
            MyCommand = new RelayCommand<string>(ExecuteMyCommand, CanExecuteMyCommand);
        }
    
        private void ExecuteMyCommand(string parameter)
        {
            // Do something
        }
    
        private bool CanExecuteMyCommand(string parameter)
        {
            // Return true or false depending on whether the command can be executed
        }
    }
    

    AsyncRelayCommand

    The AsyncRelayCommand class is the asynchronous version of RelayCommand.

    Important

    The AsyncRelayCommand class is not supported yet in WebGL builds.

    You can create an AsyncRelayCommand instance by passing an asynchronous delegate to the constructor. The delegate will be invoked when the command is executed. Optionally, you can also pass a delegate to the constructor to determine whether the command can be executed.

    You can also specify if the command accepts concurrent executions. By default, the command does not accept concurrent executions. If the command is already executing and the user invokes the command again, the second execution will be ignored. If you want to allow concurrent executions, you can set this option using AsyncRelayCommandOptions.

    public class MyViewModel : ObservableObject
    {
        public AsyncRelayCommand MyCommand { get; }
        
        public MyViewModel()
        {
            MyCommand = new AsyncRelayCommand(
                ExecuteMyCommand, 
                CanExecuteMyCommand, 
                AsyncRelayCommandOptions.AllowConcurrentExecutions);
        }
    
        private async Task ExecuteMyCommand()
        {
            // Do something
        }
    
        private bool CanExecuteMyCommand()
        {
            // Return true or false depending on whether the command can be executed
        }
    }
    

    Like RelayCommand, you can also use the generic version of AsyncRelayCommand to pass a parameter to the command delegate.

    public class MyViewModel : ObservableObject
    {
        public AsyncRelayCommand<string> MyCommand { get; }
        
        public MyViewModel()
        {
            MyCommand = new AsyncRelayCommand<string>(
                ExecuteMyCommand, 
                CanExecuteMyCommand, 
                AsyncRelayCommandOptions.AllowConcurrentExecutions);
        }
    
        private async Task ExecuteMyCommand(string parameter)
        {
            // Do something
        }
    
        private bool CanExecuteMyCommand(string parameter)
        {
            // Return true or false depending on whether the command can be executed
        }
    }
    

    Command Binding

    Usually in MVVM, you will want to bind a command to a user interface element. In App UI, you can do this by listening to events triggered by the user interface element and invoking the command when the event is triggered.

    For example, you can bind a command to a button by listening to the clicked event of a Button.

    myButton.clicked += () => MyCommand.Execute();
    

    You can also bind the CanExecuteChanged event of the command to to enable or disable the button depending on whether the command can be executed.

    MyCommand.CanExecuteChanged += (sender, args) => myButton.SetEnabled(MyCommand.CanExecute());
    
    Note

    It is up to the user to call NotifyCanExecuteChanged when the state of the command should change.

    In This Article
    • Introduction
    • Commands
      • RelayCommand
      • AsyncRelayCommand
    • Command Binding
    Back to top
    Copyright © 2024 Unity Technologies — Trademarks and terms of use
    • Legal
    • Privacy Policy
    • Cookie Policy
    • Do Not Sell or Share My Personal Information
    • Your Privacy Choices (Cookie Settings)