Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create an alert popup from my ViewModel in Xamarin?

I'm developing my Xamarin app with the MVVM pattern. I want to display an alert to the user when the user presses a button.

I declare my ViewModel with

class MainPageViewModel : BindableBase   {

Unfortunately, I'm not able to access a Page object from within the ViewModel directly. How do I best go about displaying my alert?

like image 728
Christian Avatar asked Oct 25 '18 08:10

Christian


People also ask

How do I create a pop up form in xamarin?

Xamarin. Forms has three methods on the Page class for interacting with the user via a pop-up: DisplayAlert , DisplayActionSheet , and DisplayPromptAsync . They are rendered with appropriate native controls on each platform.

What are Viewmodels xamarin?

The view model implements properties and commands to which the view can data bind to, and notifies the view of any state changes through change notification events.


3 Answers

Late to the party but as Nick Turner has mentioned in a number of comments, the solutions given so far require the view model to reference the view which is an antipattern/infringement of MVVM. Additionally, you'll get errors in your view model unit tests such as: You MUST call Xamarin.Forms.Init(); prior to using it.

Instead you can create an interface that contains the code for your alert boxes and then use in your view model as follows:

Interface:

public interface IDialogService
{ 
    Task ShowAlertAsync(string message, string title, string buttonLabel); 
}

Implementation (Using ACR.UserDialogs NuGet package):

public class DialogService : IDialogService
{
    public async Task ShowAlertAsync(string message, string title, string buttonLabel)
    {
        if (App.IsActive)
            await UserDialogs.Instance.AlertAsync(message, title, buttonLabel);            
        else
        {
            MessagingCenter.Instance.Subscribe<object>(this, MessageKeys.AppIsActive, async (obj) =>
            {
                await UserDialogs.Instance.AlertAsync(message, title, buttonLabel);
                MessagingCenter.Instance.Unsubscribe<object>(this, MessageKeys.AppIsActive);
            });
        }
    }
}

ViewModel:

public class TestViewModel
{    
    private readonly IDialogService _dialogService;

    public TestViewModel(IDialogService dialogService)
    {
         //IoC handles _dialogService implementation
         _dialogService = dialogService ?? throw new ArgumentNullException(nameof(dialogService));
    }

    public ICommand TestCommand => new Command(async () => await TestAsync());

    private async Task TestAsync()
    {
        await _dialogService.ShowAlertAsync("The message alert will show", "The title of the alert", "The label of the button");
    }
}

TestCommand can then be bound to the button in the your xaml:

<Button x:Name="testButton" Command="{Binding TestCommand}">
like image 178
Stu Stephenson Avatar answered Oct 31 '22 17:10

Stu Stephenson


To display Alert write below code in your ViewModel class

public class MainViewModel
{
    public ICommand ShowAlertCommand { get; set; }
    public MainViewModel()
    {
        ShowAlertCommand = new Command(get => MakeAlter());
    }
    void MakeAlter()
    {
        Application.Current.MainPage.DisplayAlert("Alert", "Hello", "Cancel", "ok");
    }
}

Set your Command to Button in xaml

<StackLayout>
<Button Text="Click for alert" Command="{Binding ShowAlertCommand}"
   HorizontalOptions="Center"
   VerticalOptions="CenterAndExpand" />
</StackLayout>

Set BindingContext in code behind of your xaml file. If you xaml file MainPage.xaml

public MainPage()
{
    InitializeComponent();
    BindingContext = new MainViewModel();

}
like image 31
R15 Avatar answered Oct 31 '22 19:10

R15


You can call the below code within the view model, if you are using normal MVVM pattern.

App.current.MainPage.DisplayAlert("","","");
like image 41
hashimks Avatar answered Oct 31 '22 18:10

hashimks