Search code examples
mvvmmauiclean-architecture

Mvvm with clean architecture, how to handle events in MAUI?


I am wondering how to achive clean architecture in my solution. I have projects: Core (Models, Messages, ViewModels), Mobile (Maui project -> Views), Shared (Dto project). I have: <PanGestureRecognizer PanUpdated="PanGestureRecognizer_PanUpdated"/> in my View, which I pass it to the MyViewModel via:

private void PanGestureRecognizer_PanUpdated(object sender, PanUpdatedEventArgs e)
{
    var panUpdatedCommand = ((MyViewModel)BindingContext).PanUpdatedCommand;
    panUpdatedCommand.Execute(e);
}

Here I pass the EventArgs: PanUpdatedEventArgs which depends on Maui.

Then I can't use RelayCommand in MyViewModel like this:

 [RelayCommand]
 private void PanUpdated(PanUpdatedEventArgs e)
 {
     switch (e.StatusType)
     {
         case GestureStatus.Started:
             ...

         case GestureStatus.Running:
             ...

         case GestureStatus.Canceled:
             ...

         case GestureStatus.Completed:
             ...
     }
 }

because PanUpdatedEventArgs and GestureStatus come from Maui library but my MyViewModel should be independent due to clean architecture. How can I achive that? Or should I put my ViewModel folder in Mobile layer?


Solution

  • You add CommunityToolkit MAUI, and make use of EventToCommandBehavior.

    https://learn.microsoft.com/en-us/dotnet/communitytoolkit/maui/behaviors/event-to-command-behavior

    Two important things:

    1. In the XAML (your VIEW) you bind to your command. You do not have to write code in the .cs, and call methods from your ViewModel.
    2. When you need arguments, you can use EventArgsConverter to convert the EventArgs to another type that is passed to the command.

    This is the way I use events in general.

    (The next is my opinion) I seriously doubt that this event has any reason to turn into command. This seems like a mechanical code, that if anywhere - belongs to the View itself.