1
votes

I'm working on a Xamarin Forms MvvmCross project. I'm binding a common button command on the view with a IMvxAsyncCommand on the view model, as follows:

  • View

     <views:MvxContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                       xmlns:views="clr- namespace:MvvmCross.Forms.Views;assembly=MvvmCross.Forms"
                       x:Class="TestProject.Pages.TestPage">
     <ContentView>
         <StackLayout>
             <Button Text="Test the command!" Command="{Binding TestAsyncCommand}"/>
         </StackLayout>
     </ContentView>
    

    </views:MvxContentPage>

  • View model

     namespace TestProject.ViewModels
     {
         public class TestViewModel : MvxNavigationViewModel
         {
             public TestViewModel(IMvxLogProvider logProvider, IMvxNavigationService navigationService)
                 : base(logProvider, navigation)
             {
             }
    
             public IMvxAsyncCommand TestAsyncCommand => new MvxAsyncCommand(async () => await TestAsyncCommandMethod());
    
             private async Task TestAsyncCommandMethod()
             {
                 //await some stuff
             }
         }
     }
    

Anythings seems to work fine but rarely sometimes after a pression of the button it becames disable. What could happen? It does not happen if I use Command in place of MvxAsyncCommand, like here:

public Command TestAsyncCommand => new Command(async () => await TestAsyncCommandMethod());

Note: TestAsyncCommandMethod is entirely encased in a try-catch block to avoid possible exceptions.

1
What does TestAsyncCommandMethod() look like?JKL
var ret = await Xamarin.Forms.Application.Current.MainPage.DisplayAlert(...); if (!ret) return; ret = await BackgroundBleCommunication(); if (!ret) await Xamarin.Forms.Application.Current.MainPage.DisplayAlert(...);AndreaGobs
Command is from native Xamarin.Forms,but IMvxAsyncCommand is from MvvmCross.By the way, Suggest that using public IMvxAsyncCommand TestAsyncCommand { get; private set; }.Junior Jiang

1 Answers

0
votes

I think what you are doing wrong here is that instead of creating a Property to Bind the View and the ViewModel you are using a field can you try this:

public IMvxAsyncCommand TestAsyncCommand {get; set;}

And then in your constructor do this:

public TestViewModel(IMvxLogProvider logProvider, IMvxNavigationService navigationService)
        : base(logProvider, navigation)
    {
      TestAsyncCommand = new MvxAsyncCommand(async () => await TestAsyncCommandMethod());
    }

UPDATE

This seems to be a bug with MvvmCross! Issue can be found in the added link

https://github.com/MvvmCross/MvvmCross/issues/1589