使用MvvmCross从ViewModel显示AlertDialog

前端之家收集整理的这篇文章主要介绍了使用MvvmCross从ViewModel显示AlertDialog前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我使用MvvmCross创建我的 Android应用程序,我面临以下问题:

当我试图显示viewmodel中创建的AlertDialog时,

出现“未处理的异常:Android.Views.WindowManagerBadTokenException”.

public class Myviewmodel : Mvxviewmodel
{
    public ICommand ShowAlertCommand { get; private set; }

    public Authorizationviewmodel()
    {
        ShowAlertCommand = new MvxCommand(() =>
            {
                var adb = new AlertDialog.Builder(Application.Context); 
                adb.SetTitle("Title here");
                adb.SetMessage("Message here");  
                adb.SetIcon(Resource.Drawable.Icon);
                adb.SetPositiveButton("OK",(sender,args) => { /* some logic */});   
                adb.SetNegativeButton("Cancel",args) => { /* close alertDialog */});

                adb.Create().Show();
            });
    }
}

当我是researching时,我发现它的发生是因为传递了对Context的引用而不是AlertDialog.Builder中的Activity.

this topic年,我发现了以下决定:
通过使用GetService()接收对当前Activity的引用,但我没有找到mvvmcross插件用于IMvxServiceConsumer,IMvxAndroidCurrentTopActivity接口.

我的问题是我可以从viewmodel显示AlertDialog吗?我怎样才能获得对Activity的引用,而不是Application.Context?
什么是关闭AlertDialog的正确方法,用户将留在当前视图?

解决方法

通常,您应该尝试不将此类代码放入viewmodel中

>因为viewmodels应该保持与平台无关
>因为viewmodels应该是可单元测试的 – 当代码显示对话框时很难进行单元测试

我还建议你不要在viewmodel构造函数中放置这样的代码 – 这些构造函数通常在导航期间调用,并且在转换期间显示Dialog可能会有问题.

有了这些说法,如果你想在任何代码中掌握当前的顶级Activity,那么你可以使用IMvxAndroidCurrentTopActivity来做到这一点.

public interface IMvxAndroidCurrentTopActivity
{
    Activity Activity { get; }
}

使用此,任何代码都可以使用以下命令获取当前活动:

var top = Mvx.Resolve<IMvxAndroidCurrentTopActivity>();
var act = top.Activity;
if (act == null)
{
   // this can happen during transitions
   // - you need to be sure that this won't happen for your code
   throw new MvxException("Cannot get current top activity");
}

var dlg = new AlertDialog.Builder(act); 
//...
dlg.Create().Show();

MvvmCross: How to pass Android context down to MvxCommand?中讨论了IMvxAndroidCurrentTopActivity的使用

在该问题/答案中采用的方法也是我通常从viewmodel显示对话框的方法之一:

>我会创建一个IFooDialog接口
>理想情况下,我可能会使这个接口异步 – 例如使用异步或使用Action< DialogResult>回调参数
>在每个平台上,我都会在UI项目中实现它
>然后,当需要对话框时,viewmodel可以使用IFooDialog,并且每个平台都可以使用适当的UI操作进行响应

这种“对话服务”类型的方法在Mvvm中很常见 – 例如看到像http://www.codeproject.com/Articles/36745/Showing-Dialogs-When-Using-the-MVVM-Pattern这样的文章(虽然那篇文章非常适合Windows!)

此处还有一些关于MvvmCross和对话框的其他问题 – 尽管它们可能包含对较早的v1或vNext代码的引用 – 例如Alerts or Popups in MvvmCrossUnable run ProgressDialog – BadTokenException while showind

猜你在找的Android相关文章