Reputation: 4332
I want to display alert from ViewModel
.
problem: The name DisplayAlert
does not exist in the current context
How to do that? Below is my code.
-- XAML
<Button x:Name="BtnLogin" Command="{Binding LoginCommand}" BackgroundColor="Green" TextColor="White" WidthRequest="150" HeightRequest="60" Text="Login" />
--- ViewModel :
class LoginViewModel : ViewModelBase
{
private string _username;
public string Username
{
get { return _username; }
set
{
_username = value;
OnPropertyChanged();
}
}
private string _password;
public string Password
{
get { return _password; }
set
{
_password = value;
OnPropertyChanged();
}
}
public LoginViewModel()
{
}
public Command LoginCommand
{
get
{
return new Command(ValidateUser);
}
}
async void ValidateUser()
{
if (_username.Length > 1 && _password.Length > 1)
{
//await DisplayAlert("Login", "Login Success", "Ok");
//--Update:
UserDialogs.Instance.Alert("Login Success", "Login", "OK");
}
else
{
// display invalid credential
}
}
Update There are a) Acr.UserDialogs V6.5.1 b) Acr.XamForms.UserDialog v5.0.0
I am using the older version which is (b) since I m using PCL .
I did import it and change the code to use it as above. But there is err msg: using Acr.UserDialogs;
Err Msg:
Java.Lang.NullPointerException: Exception of type 'Java.Lang.NullPointerException' was thrown.
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <3fd174ff54b146228c505f23cf75ce71>:0
at Java.Interop.JniEnvironment+InstanceMethods.CallNonvirtualVoidMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00089] in <bd30a18775d94dc8b6263aecd1ca9077>:0
at Java.Interop.JniPeerMembers+JniInstanceMethods.FinishCreateInstance (System.String constructorSignature, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x0004f] in <bd30a18775d94dc8b6263aecd1ca9077>:0
at Android.App.AlertDialog+Builder..ctor (Android.Content.Context context) [0x0007a] in <d855bac285f44dda8a0d8510b679b1e2>:0
at Acr.UserDialogs.Builders.AlertBuilder.Build (Android.App.Activity activity, Acr.UserDialogs.AlertConfig config) [0x0000d] in <addbf2648c204949b40c582bd49b7ddd>:0
at Acr.UserDialogs.UserDialogsImpl.Alert (Acr.UserDialogs.AlertConfig config) [0x00038] in <addbf2648c204949b40c582bd49b7ddd>:0
at Acr.UserDialogs.AbstractUserDialogs.Alert (System.String message, System.String title, System.String okText) [0x00024] in <ec0104dbfc974343b668f7b28f49a1ab>:0
at BookingNow.ViewModel.LoginViewModel.ValidateUser () [0x00026] in C:\Users\Edward\documents\visual studio 2017\Projects\BookingNow\BookingNow\BookingNow\ViewModel\LoginViewModel.cs:88
--- End of managed Java.Lang.NullPointerException stack trace ---
java.lang.NullPointerException
at android.app.AlertDialog.resolveDialogTheme(AlertDialog.java:143)
at android.app.AlertDialog$Builder.<init>(AlertDialog.java:360)
at md5270abb39e60627f0f200893b490a1ade.ButtonRenderer_ButtonClickListener.n_onClick(Native Method)
at md5270abb39e60627f0f200893b490a1ade.ButtonRenderer_ButtonClickListener.onClick(ButtonRenderer_ButtonClickListener.java:30)
at android.view.View.performClick(View.java:4476)
at android.view.View$PerformClick.run(View.java:18787)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5493)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
at dalvik.system.NativeStart.main(Native Method)
Thanks
Upvotes: 23
Views: 28582
Reputation: 2111
public interface IMessageService
{
Task ShowAsync(string message);
}
public class MessageService : IMessageService
{
public async Task ShowAsync(string message)
{
await App.Current.MainPage.DisplayAlert("YourApp", message, "Ok");
}
}
public partial class App : Application
{
public App()
{
//Add the next line
DependencyService.Register<ViewModels.Services.IMessageService, Views.Services.MessageService>();
InitializeComponent();
MainPage = new MainPage();
}
}
public class YourViewModel
{
private readonly Services.IMessageService _messageService;
public YourViewModel()
{
this._messageService = DependencyService.Get<Services.IMessageService>();
//Show the dialog with next line
_messageService.ShowAsync("Hi!!!");
}
}
Upvotes: 27
Reputation: 87
You need to pass the Page to the ViewModel
In your view pass the page to the ViewModel with 'this'
public partial class ThePage : ContentPage
{
ViewModel viewModel;
public ThePage()
{
InitializeComponent();
viewModel = new ViewModel(this);
}
and then in your view model
public class ViewModel
{
Page page;
public ViewModel(Page page)
{
this.page = page;
//SOME CODE
}
async void ValidateUser()
{
await page.DisplayAlert("Alert from View Model", "", "Ok");
}
}
Upvotes: 2
Reputation: 34013
If you want to keep it pure, you should probably refrain from using alerts in the traditional way and find some way to collect input that you can trigger from toggling a property.
However, there is another, simpler way. You could use ACR.UserDialogs. If you're not using .NET Standard yet you will need to install an older version of the NuGet package. Remember to install it in both your shared project as well as the platform projects. It might also need some initialization code depending on the platform, make sure to check the readme.
You can now either call the instance directly with: UserDialogs.Instance
and then a method to show an alert or whatever you need. To keep it a bit more MVVM like you could also register this instance with it's interface counterpart and have it injected into your view models.
Upvotes: 5