我正在使用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", (sender, args) => { /* close alertDialog */});
adb.Create().Show();
});
}
}
当我researching时,我发现它的发生是因为传递了对Context的引用而不是AlertDialog.Builder中的Activity。
在this topic我发现了以下决定: 通过使用GetService()接收对当前Activity的引用,但我没有找到mvvmcross插件用于IMvxServiceConsumer,IMvxAndroidCurrentTopActivity接口。
我的问题是否可以从ViewModel显示AlertDialog?我怎样才能获得对Activity的引用,而不是Application.Context? 什么是关闭AlertDialog的正确方法,用户将保留在当前视图?
答案 0 :(得分:12)
通常,您应该尝试不将此类代码放入ViewModels
我还建议您不要在ViewModel构造函数中放置这样的代码 - 这些构造函数通常在导航期间调用,并且在转换期间显示Dialog可能会有问题。
有了这些说法,如果您确实希望在任何代码中掌握当前的顶级活动,那么您可以使用IMvxAndroidCurrentTopActivity
public interface IMvxAndroidCurrentTopActivity
{
Activity Activity { get; }
}
使用此代码,任何代码都可以使用:
获取当前Activity
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
界面async
或使用Action<DialogResult>
回调参数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 MvvmCross和Unable run ProgressDialog - BadTokenException while showind