gpt4 book ai didi

mvvm - 使用 MvvmCross 从 ViewModel 显示 AlertDialog

转载 作者:行者123 更新时间:2023-12-04 13:40:32 25 4
gpt4 key购买 nike

我正在使用 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我发现它发生是因为对上下文的引用而不是在 AlertDialog.Builder 中的 Activity 上的传输。

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

我的问题 我可以从 ViewModel 显示 AlertDialog 吗?以及如何获得对 Activity 的引用,而不是对 Application.Context 的引用?
关闭用户将留在当前 View 上的 AlertDialog 的正确方法是什么?

最佳答案

一般来说,你应该尽量不要把这种类型的代码放到 ViewModels 中

  • 因为 ViewModel 应该保持平台独立
  • 因为 ViewModel 应该是可单元测试的 - 当代码显示一个对话框时很难进行单元测试

  • 我还建议您不要将这样的代码放在 ViewModel 构造函数中 - 这些构造函数通常在导航期间调用,并且在转换期间显示对话框可能会出现问题。

    说了这么多,如果你确实想在任何代码中获取当前的顶级事件,那么你可以使用 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();

    使用 IMvxAndroidCurrentTopActivityMvvmCross: How to pass Android context down to MvxCommand? 中讨论

    该问题/答案中采用的方法也是我通常会从 ViewModel 显示对话框的方法之一:
  • 我会创建一个 IFooDialog接口(interface)
  • 理想情况下,我可能会让这个接口(interface)异步 - 例如使用 async或使用 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

    关于mvvm - 使用 MvvmCross 从 ViewModel 显示 AlertDialog,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17037280/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com