代码之家  ›  专栏  ›  技术社区  ›  Trevor Balcom

通过后退按钮取消MvxAppCompatDialogFragment未完全工作

  •  1
  • Trevor Balcom  · 技术社区  · 7 年前

    关闭a MvxAppCompatDialogFragment Task 卡住了。如果我改为 MvxDialogFragment 然后,后退按钮将按预期关闭对话框,我单击以触发对话框的按钮将在对话框关闭后再次启用。我正在尝试使用 因为我正在使用 MvxAppCompatActivity . 我是否做错了什么,或者这是MvvmCross 5.2.1中的一个错误?

    以下是ViewModel:

    public class ConfirmationViewModel : MvxViewModel<ConfirmationConfiguration, bool?>, IMvxLocalizedTextSourceOwner
    {
        private readonly IMvxNavigationService _mvxNavigationService;
    
        public ConfirmationViewModel(IMvxNavigationService mvxNavigationService)
        {
            _mvxNavigationService = mvxNavigationService;
        }
    
        public override void Prepare([NotNull] ConfirmationConfiguration parameter)
        {
            if (parameter == null) throw new ArgumentNullException(nameof(parameter));
            Title = parameter.Title;
            Body = parameter.Body;
            PositiveCommandText = !string.IsNullOrEmpty(parameter.YesCommandText) 
                ? parameter.YesCommandText 
                : LocalizedTextSource.GetText("Yes");
            NegativeCommandText = !string.IsNullOrEmpty(parameter.NoCommandText)
                ? parameter.NoCommandText
                : LocalizedTextSource.GetText("No");
        }
    
        private bool? _confirmationResult;
        public bool? ConfirmationResult
        {
            get => _confirmationResult;
            private set => SetProperty(ref _confirmationResult, value);
        }
    
        private string _title;
        public string Title
        {
            get => _title;
            set => SetProperty(ref _title, value);
        }
    
        private string _body;
        public string Body
        {
            get => _body;
            set => SetProperty(ref _body, value);
        }
    
        private string _positiveCommandText;
        public string PositiveCommandText
        {
            get => _positiveCommandText;
            set => SetProperty(ref _positiveCommandText, value);
        }
    
        private string _negativeCommandText;
        public string NegativeCommandText
        {
            get => _negativeCommandText;
            set => SetProperty(ref _negativeCommandText, value);
        }
    
        private IMvxAsyncCommand _yesCommand;
        public IMvxAsyncCommand PositiveCommand => _yesCommand ?? (_yesCommand = new MvxAsyncCommand(OnPositiveCommandAsync));
    
        private async Task OnPositiveCommandAsync()
        {
            ConfirmationResult = true;
            await _mvxNavigationService.Close(this, ConfirmationResult);
        }
    
        private IMvxAsyncCommand _noCommand;
        public IMvxAsyncCommand NegativeCommand => _noCommand ?? (_noCommand = new MvxAsyncCommand(OnNegativeCommandAsync));
    
        private async Task OnNegativeCommandAsync()
        {
            ConfirmationResult = false;
            await _mvxNavigationService.Close(this, ConfirmationResult);
        }
    
        public IMvxLanguageBinder LocalizedTextSource => new MvxLanguageBinder("", GetType().Name);
    
        public IMvxLanguageBinder TextSource => LocalizedTextSource;
    }
    
    public class ConfirmationConfiguration
    {
        public string Title { get; set; }
        public string Body { get; set; }
        public string YesCommandText { get; set; }
        public string NoCommandText { get; set; }
    }
    

    以下是视图:

    [MvxDialogFragmentPresentation(Cancelable = true)]
    [Register(nameof(ConfirmationFragment))]
    public class ConfirmationFragment : MvxAppCompatDialogFragment<ConfirmationViewModel>
    {
        public ConfirmationFragment()
        {
            RetainInstance = true;
        }
    
        public ConfirmationFragment(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
        {
            RetainInstance = true;
        }
    
        public override Dialog OnCreateDialog(Bundle savedInstanceState)
        {
            var builder = new AlertDialog.Builder(Activity)
                .SetTitle(ViewModel.Title)
                .SetMessage(ViewModel.Body)
                .SetPositiveButton(ViewModel.PositiveCommandText, OnPositiveButton)
                .SetNegativeButton(ViewModel.NegativeCommandText, OnNegativeButton);
            return builder.Create();
        }
    
        private async void OnNegativeButton(object sender, DialogClickEventArgs e)
        {
            if (ViewModel.NegativeCommand.CanExecute())
            {
                await ViewModel.NegativeCommand.ExecuteAsync();
            }
        }
    
        private async void OnPositiveButton(object sender, DialogClickEventArgs e)
        {
            if (ViewModel.PositiveCommand.CanExecute())
            {
                await ViewModel.PositiveCommand.ExecuteAsync();
            }
        }
    }
    

    我导航到这样的对话框:

            var confirmation = await Mvx.Resolve<IMvxNavigationService>().Navigate<ConfirmationViewModel, ConfirmationConfiguration, bool?>(
                new ConfirmationConfiguration()
                {
                    Body = "Hello, World!",
                    Title = "Testing"
                });
    

    如果我将基类从 MvxAppCompatDialogFragment MvxDialogFragment 然后一切如期进行。

    2 回复  |  直到 7 年前
        1
  •  2
  •   nmilcoff    7 年前

    这确实是MvvmCross v5.2.1中的一个问题(感谢您的报告!)。作为暂时的解决方法,您可以在DialogFragment类中添加以下代码:

    public override void OnCancel(IDialogInterface dialog)
    {
        base.OnCancel(dialog);
        ViewModel?.ViewDestroy();
    }
    
    public override void DismissAllowingStateLoss()
    {
        base.DismissAllowingStateLoss();
        ViewModel?.ViewDestroy();
    }
    
    public override void Dismiss()
    {
        base.Dismiss();
        ViewModel?.ViewDestroy();
    }
    
        2
  •  2
  •   Martijn00    7 年前

    我已经调查过了。当你按下后退按钮时,它会关闭视图而不调用 NavigationSerivce.Close() . 这会阻止结果 Task 并设置或取消操作。我不确定这是一个bug还是仅仅是一种行为。解决方法可以是打电话 Close ConfirmationViewModel ViewDissapearing ,或取消 任务 你自己