If you are following MVVM, having the exception handled in the ViewModels helps you avoid losing control without your application crashing at random times. The logic for error handling can be extended into BaseViewModel.
You can extend BaseViewModel with a property of type ErrorMessage to host the current error state.
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace MauiAppExample.ViewModels
{
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetProperty<T>(ref T backingStore, T value, [CallerMemberName] string propertyName = "")
{
if (EqualityComparer<T>.Default.Equals(backingStore, value))
return false;
backingStore = value;
OnPropertyChanged(propertyName);
return true;
}
private string errorMessage;
public string ErrorMessage
{
get => errorMessage;
set => SetProperty(ref errorMessage, value);
}
protected void HandleError(Exception ex)
{
// Set the error message that can be displayed in the View
ErrorMessage = ex.Message;
// Optionally log the error (you could use a logging service here)
System.Diagnostics.Debug.WriteLine($"Error: {ex.Message}");
}
}
}
ErrorMessage: A property that can be bound to the View for error messages.
HandleError
: This method can be invoked to handle and log errors in a standard format.
Using Error Handling in ViewModel
using System.Collections.ObjectModel;
using System.Windows.Input;
using MauiAppExample.Models;
namespace MauiAppExample.ViewModels
{
public class ProductViewModel : BaseViewModel
{
private string newProductName;
public string NewProductName
{
get => newProductName;
set => SetProperty(ref newProductName, value);
}
public ObservableCollection<Product> Products { get; } = new ObservableCollection<Product>();
public ICommand AddProductCommand { get; }
public ProductViewModel()
{
AddProductCommand = new Command(OnAddProduct);
}
private void OnAddProduct()
{
try
{
if (string.IsNullOrWhiteSpace(NewProductName))
throw new ArgumentException("Product name cannot be empty.");
Products.Add(new Product { Name = NewProductName });
NewProductName = string.Empty; // Reset the input field after adding the product
}
catch (Exception ex)
{
HandleError(ex);
}
}
}
}