Alert Dialog in ViewModel - MVVMCross
Asked Answered
H

5

11

In the ViewModel, I have Save method where I check isValid property.

If isValid is false, then I want to display an error message.

Since AlertDialog is platform specific, I wonder how do you handle that situation in the ViewModel?

public void Save()
{
  if (isValid)
  {
      OnExit(this, null);
   }
   else
   {
      //issue an alert dialog here
   }
}

Update

I have used the following plugin and added the following line of code as follows, but it throws an error.

else
{
    Mvx.Resolve<IUserInteraction>().Alert("it is not valid");
}

enter image description here

Update 2

Chance.MvvmCross.Plugins.UserInteraction is a namespace but it is used as a type error.

enter image description here

Update 3

I have added Acr.UserDialogs plugin and called as follows, but I have got the same error.

Mvx.Resolve<IUserDialogs>().Alert("it is not valid");

enter image description here

Hyperthyroidism answered 11/5, 2016 at 16:33 Comment(5)
Did you add the nuget to the Android and iOS projects as well ?Iyre
Yes I have added PCL, Android and iOS. I could able to see Chance.MvvmCross.Plugins.UserInteraction.Droid and Chance.MvvmCross.Plugins.UserInteraction in the Android SolutionHyperthyroidism
I just noticed that the Mvvmcross plugin has not been kept up to date and some dependencies can not be resolved. I would suggest you use a different plugin: github.com/aritchie/userdialogs You can also find a full list of xamarin plugins here:github.com/xamarin/XamarinComponentsIyre
Please see my updateHyperthyroidism
Do you get an exception when attempting to display the alert ? anything in the log ? I am sure you already did this but did you register IUserDialog in the app.cs in the PCL project ? Mvx.RegisterSingleton<IUserDialogs>(() => UserDialogs.Instance);Iyre
A
11

Using ACR User Dialogs is the simplest approach.

In your App.cs (Core/PCL) you will need to register the interface:

public class App : MvxApplication
{
    public override void Initialize()
    {
       // Example Other registrations
        CreatableTypes()
            .EndingWith("Service")
            .AsInterfaces()
            .RegisterAsLazySingleton();

        Mvx.RegisterSingleton<IUserDialogs>(() => UserDialogs.Instance);
    }
}

Then you can call your alert form your ViewModel.

Mvx.Resolve<IUserDialogs>().Alert("it is not valid");

Note for Android Platform support

Then if you are supporting Android you will need to initialize UserDialog with an instance of the activity context. This will have to be done in each activity that you will be making use of UserDialogs or if you have a shared base activity you can do it there.

[Activity]
public class MainActivity : MvxActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        SetContentView(Resource.Layout.activity_main);

        // Initialize Acr UserDialogs
        UserDialogs.Init(this);
    }
}

Alternatively

You can follow the Mvvmcross document on using platform specific implementations of an interface if you need a more custom modal implementation.

Auspex answered 12/5, 2016 at 16:16 Comment(5)
If I need to use it in the iOS, UserDialogs.Init(this); needs to go where?Hyperthyroidism
@hotspring, nope iOS requires no additional actions :)Auspex
iOS and Windows = "Nothing is necessary any longer as of v4.x" GithubAuspex
Thanks for answer.Oregon
Android requires in main activity: UserDialogs.Init(() => Mvx.Resolve<IMvxAndroidCurrentTopActivity>().Activity). See Setup section on GitHubRonn
S
4

This is how I handle the Alert messages in the viewmodel. Try this.

await App.Current.MainPage.DisplayAlert("Active subscription required", "You do not have an active subscription for Part 2 exams", "OK");
Sweptwing answered 12/5, 2016 at 11:10 Comment(7)
Could you please elaborate Current.MainPage.DisplayAlert("xxxx"); ?Hyperthyroidism
This is a built-in xamarin forms method in Xamarin.Forms.Core.dll that you should be able to simply reach from your viewmodel by just typing the code that I wrote above. This built-in xamarin forms method presents an alert dialog to the application user with a single cancel button. For more details and some more sample code please see this link.Sweptwing
When I type App, then App. does not show any options in my case. It only shows Reference or Equals property.Hyperthyroidism
I have just created a new test Xamarin Portable app and I can reach the method without doing anything else. please see below;Sweptwing
This is the documentation to create a xamarin portable app and here is my test app's code that I just created. public App() { // The root page of your application App.Current.MainPage.DisplayAlert("Test Title", "Test Message", "Cancel text"); }Sweptwing
@hotspring is this a Xamarin.Forms app, if not the displayalert() won't be available unless you implement your own!Iyre
It is not a Xamarin.Form application.Hyperthyroidism
I
2

There is an existing MvvmCross plugin called User Interaction that allows displaying alerts and collecting inputs from ViewModels.

From the author BrianChance:

Really simple, easy, beautiful ways to show a message box or to collect user input from your ViewModels

Check it out here and NuGet Link Here.

To install the plugin, make sure you override LoadPlugins in your SetUp Class on iOS and Android (and windows phone) like so:

public override void LoadPlugins(MvvmCross.Platform.Plugins.IMvxPluginManager pluginManager)
{
    base.LoadPlugins(pluginManager);
    pluginManager.EnsurePluginLoaded<Chance.MvvmCross.Plugins.UserInteraction>();

}
Iyre answered 11/5, 2016 at 16:39 Comment(1)
I have added that plugin and run the app and received an error. Please see my updated question.Hyperthyroidism
A
1

My approach is that i use an event for this scenario. My base class for my view models has a EventHandler OnUserNotification, where the views can kinda subscribe to. The UserNotificationType is just an enum and i let the view kinda decide how it reacts to the situation.

The property:

public EventHandler<UserNotificationType> OnUserNotification { get; set; }

The call:

 if (OnUserNotification != null)
 {
   OnUserNotification.Invoke(this, UserNotificationType.ENetworkError);
 }

In the view:

private void onUserNotification(object sender, UserNotificationType userNotificationType)
{
     // Do Something like showing a Snackbar, AlertDialog, etc...
}

Of course you can make the eventtype more complex if needed.

Didnt try the plugin which got suggested by wishmaster though, so that might be a smoother implementation?

Alenealenson answered 12/5, 2016 at 6:43 Comment(2)
What am I supposed to put in the else condition ? could you please provide a little bit more information?Hyperthyroidism
If you mean your else condition, you would use OnUserNotification.Invoke(this, UserNotificationType.EExampleError). And then you can handle the notification event in the view. Just be sure that the view attaches the method to the Eventhandler with ViewModel.OnUserNotification += onUserNotification; or whatever your method is called.Alenealenson
L
1

Use Acr.UserDialogs. There is a great examples on github

You can grab it on nuget

It works well with dependency injection or a static singleton UserDialogs.Instance

Leatherette answered 13/5, 2016 at 18:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.