CommunityToolkit / MVVM-Samples

Sample repo for MVVM package
Other
1.13k stars 220 forks source link

[RelayCommand] accepting multiple taps and executing the command multiple times #105

Open bradyguyc opened 1 year ago

bradyguyc commented 1 year ago

Per the documentation on the [RelayCommand] source generator I believe that by default that multiple taps on a button should not execute the same command multiple times. However, I am experiencing the situation where I load a page from a tap gesture command and the page gets pushed multiple times. Trying to figure out how to prevent this from happening. Is this a bug or is there something missing in the code that prevents this from happening.

https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/generators/relaycommand#handling-concurrent-executions

This can be observed in this test app https://bradyguychambers@dev.azure.com/bradyguychambers/MyNextBook/_git/Test%20Multiple%20Taps

 <ContentView.GestureRecognizers>
       <TapGestureRecognizer Command="{Binding Source={RelativeSource AncestorType={x:Type local:MySeriesPageViewModel}}, Path=TapCommand}" CommandParameter="{Binding .}" />
 </ContentView.GestureRecognizers>
 [RelayCommand]
        private async void Tap(object param)
        {
            try
            {
                System.Diagnostics.Debug.WriteLine("SelectionTap:" );

                if (param != null)
                {
                    Series s = (Series)param;
                    System.Diagnostics.Debug.WriteLine("SelectionTap:" + s.Name);
                     await Shell.Current.GoToAsync($"booksview?name={s.Name}");

                }
            }
            catch (Exception ex)
            {
                //todo: call appcenter analytics
                System.Diagnostics.Debug.WriteLine("Crash: " + ex.Message);
            }
        }

This can be observed in this test app. https://bradyguychambers@dev.azure.com/bradyguychambers/MyNextBook/_git/Test%20Multiple%20Taps

ryanvs commented 1 year ago

I believe you can provide add property for controlling the CanExecute of the RelayCommand to prevent simultaneous executions.

private bool canTap;

public bool CanTap
{
    get => canTap;
    private set => SetProperty(ref canTap, value);
}

[RelayCommand(CanExecute = "CanTap")]
public async void Tap(object param)
{
    try
    {
        CanTap = false;
        // ....<snipped/>...
    }
    finally
    {
        CanTap = true;
    }
}

It makes me wonder if there should be a [AsyncRelayCommand] source generator as well.

ketakidevendra commented 3 weeks ago

Is there any update on this??

bradyguyc commented 3 weeks ago

@ketakidevendra I have not experienced this problem in some time. I believe it was fixed in one of the many updates since I opened this ticket. I need to test and verify but have not noticed it happening in my app.

ketakidevendra commented 2 weeks ago

@bradyguyc - I face this in iOS.