如何从 ViewModel 显示警报

Mil*_*tle 14 xamarin.forms

我想显示来自ViewModel.

问题:名称DisplayAlert在当前上下文中不存在

怎么做?下面是我的代码。

-- 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
            }
        }
Run Code Online (Sandbox Code Playgroud)

更新 有 a) Acr.UserDialogs V6.5.1 b) Acr.XamForms.UserDialog v5.0.0

我使用的是 (b) 的旧版本,因为我使用的是 PCL 。

我确实导入了它并更改了代码以如上所述使用它。但是有 err msg: using Acr.UserDialogs;

错误消息:

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)
Run Code Online (Sandbox Code Playgroud)

谢谢

Dav*_*sus 11

  1. 创建接口:
public interface IMessageService
{
    Task ShowAsync(string message);
}
Run Code Online (Sandbox Code Playgroud)
  1. 实现接口:
public class MessageService : IMessageService
{
    public async Task ShowAsync(string message)
    {
        await App.Current.MainPage.DisplayAlert("YourApp", message, "Ok");
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. 将依赖服务注入 App 类:
public partial class App : Application
{
    public App()
    {
        //Add the next line
        DependencyService.Register<ViewModels.Services.IMessageService, Views.Services.MessageService>();
        InitializeComponent();
        MainPage = new MainPage();
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. 在您的 ViewModel 中初始化它并使用:
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!!!");
    }
}
Run Code Online (Sandbox Code Playgroud)


Ger*_*uis 5

如果您想保持纯粹,您可能应该避免以传统方式使用警报,并找到某种方法来收集可以通过切换属性触发的输入。

然而,还有另一种更简单的方法。您可以使用ACR.UserDialogs。如果您尚未使用 .NET Standard,则需要安装旧版本的 NuGet 包。请记住将其安装在您的共享项目以及平台项目中。根据平台的不同,它可能还需要一些初始化代码,请务必检查自述文件。

现在,您可以直接使用以下方法调用实例:UserDialogs.Instance然后是显示警报的方法或您需要的任何内容。为了使其更像 MVVM,您还可以使用其对应的接口来注册该实例,并将其注入到您的视图模型中。

  • 这有效:await Application.Current.MainPage.DisplayAlert("Login", "Login Success", "Ok"); 但我的项目中没有 MainPage.xaml。我删除了它。为什么这有效? (9认同)
  • “Application.Current.MainPage”并不指向名为“MainPage”的文件或类,它是“App”对象的属性,包含设置为应用程序主页的页面。所以它可以是任何页面。 (3认同)