How to display alert from ViewModel

生来就可爱ヽ(ⅴ<●) 提交于 2021-02-06 20:42:32

问题


newbie here. 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


回答1:


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.




回答2:


  1. Create an interface:
public interface IMessageService
{
    Task ShowAsync(string message);
}
  1. Implement the interface:
public class MessageService : IMessageService
{
    public async Task ShowAsync(string message)
    {
        await App.Current.MainPage.DisplayAlert("YourApp", message, "Ok");
    }
}
  1. Inject the dependency service into App class:
public partial class App : Application
{
    public App()
    {
        //Add the next line
        DependencyService.Register<ViewModels.Services.IMessageService, Views.Services.MessageService>();
        InitializeComponent();
        MainPage = new MainPage();
    }
}
  1. Initialize it in your ViewModel and use:
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!!!");
    }
}



回答3:


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");
    }
 }


来源:https://stackoverflow.com/questions/45277046/how-to-display-alert-from-viewmodel

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!