| MAUI-CommunityToolkit-2 :👈 | 👉:MAUI-CommunityToolkit-4 |
๐ Hour 3 โ Commands: RelayCommand & AsyncRelayCommand |
Commands are an MVVM-friendly way to handle user interactions without writing code-behind. A Command is an object that implements ICommand and allows executing logic from UI elements like:
Why use commands instead of Click events?
RelayCommand is a simple command used for synchronous actions.
Basic Example:
public partial class CounterViewModel : ObservableObject
{
[ObservableProperty]
private int count;
public RelayCommand IncreaseCommand { get; }
public CounterViewModel()
{
IncreaseCommand = new RelayCommand(() =>
{
Count++;
});
}
}
โ Bind this in XAML:
<Button Text="Increase" Command="{Binding IncreaseCommand}" />
๐ก Every click increments the count using MVVM-friendly logic.
Example:
public RelayCommand<int> AddCommand { get; }
public CounterViewModel()
{
AddCommand = new RelayCommand<int>((value) =>
{
Count += value;
});
}
XAML binding:
<Button Text="+5" Command="{Binding AddCommand}" CommandParameter="5" />
๐ Now you can pass custom values from UI.
Use AsyncRelayCommand when your logic is asynchronous, such as:
Example:
public partial class DataViewModel : ObservableObject
{
[ObservableProperty]
private string message;
public IAsyncRelayCommand LoadCommand { get; }
public DataViewModel()
{
LoadCommand = new AsyncRelayCommand(LoadDataAsync);
}
private async Task LoadDataAsync()
{
Message = "Loading...";
await Task.Delay(2000);
Message = "Data Loaded Successfully!";
}
}
XAML:
<Button Text="Load" Command="{Binding LoadCommand}" />
๐ก AsyncRelayCommand automatically disables itself while running.
Commands can control whether buttons are enabled using CanExecute.
Example:
public RelayCommand SubmitCommand { get; }
public LoginViewModel()
{
SubmitCommand = new RelayCommand(
Submit,
() => !string.IsNullOrEmpty(Username)
);
}
XAML:
<Button Text="Submit" Command="{Binding SubmitCommand}" />
๐ก The button becomes disabled when Username is empty.
MVVM Toolkit can create commands automatically with the [ICommand] attribute.
Example:
public partial class NumberViewModel : ObservableObject
{
[ObservableProperty]
private int total;
[ICommand]
private void Add(int value)
{
Total += value;
}
}
โ This automatically generates an AddCommand.
XAML:
<Button Text="Add 10" Command="{Binding AddCommand}" CommandParameter="10" />
public partial class DemoViewModel : ObservableObject
{
[ObservableProperty]
private int counter;
[ObservableProperty]
private bool isBusy;
public RelayCommand IncreaseCommand { get; }
public RelayCommand<int> AddAmountCommand { get; }
public IAsyncRelayCommand LoadCommand { get; }
public DemoViewModel()
{
IncreaseCommand = new RelayCommand(() => Counter++);
AddAmountCommand = new RelayCommand<int>((value) => Counter += value);
LoadCommand = new AsyncRelayCommand(LoadAsync);
}
private async Task LoadAsync()
{
IsBusy = true;
await Task.Delay(2000);
Counter += 10;
IsBusy = false;
}
}
๐ Covers all command types!
Consider this ViewModel:
public partial class DemoViewModel : ObservableObject
{
[ObservableProperty]
private int score = 0;
[ICommand]
private void AddPoints(int value)
{
Score += value;
}
}
Given:
public RelayCommand SaveCommand { get; }
public ExampleViewModel()
{
SaveCommand = new RelayCommand(
Save,
() => IsFormValid
);
}
[ObservableProperty] private string title;
partial void OnScoreChanged(int value)
{
Console.WriteLine("Score changed!");
}
| MAUI-CommunityToolkit-2 :👈 | 👉:MAUI-CommunityToolkit-4 |