2017-09-27 81 views
0

通過後退按鈕關閉MvxAppCompatDialogFragment似乎不能完全正常工作。在對話框關閉後,我點擊的按鈕來觸發對話框保持禁用狀態。這幾乎就像Task卡住了。如果我更改爲MvxDialogFragment,則後退按鈕將按預期關閉對話框,並在對話框關閉後再次啓用觸發對話框的按鈕。我正嘗試使用MvxAppCompatDialogFragment,因爲我正在使用MvxAppCompatActivity。我做錯了什麼或者這是MvvmCross 5.2.1中的錯誤?通過Back按鈕取消MvxAppCompatDialogFragment取消不完全

這裏是視圖模型:

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" 
      }); 

如果我換基從MvxAppCompatDialogFragmentMvxDialogFragment,然後它按預期工作。

+0

我想你也使用'MvxAppCompatPresenter'?我必須研究這一點,因爲測試項目也使用'MvxDialogFragment'參見https://github.com/MvvmCross/MvvmCross/blob/develop/TestProjects/Playground/Playground.Droid/Views/ModalView.cs – Martijn00

+0

是的,我正在使用'MvxAppCompatPresenter'。它由'MvxAppCompatSetup'引入。 –

回答

1

這確實是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(); 
} 
1

我已經看過這個。會發生什麼情況是,當您按下後退按鈕時,它會關閉視圖而不會調用NavigationSerivce.Close()。這可以防止調用結果Task並設置或取消操作。我不確定這是一個錯誤還是僅僅是行爲。解決方法可以從ConfirmationViewModelViewDissapearing撥打Close,或自行取消Task

+0

我不認爲這是一個很好的解決方法。從'ViewDisappearing'調用'Close'會使對話框永遠不會出現屏幕旋轉。如果我打開對話框,然後旋轉設備,則調用「ViewDisappearing」。這是我期望框架處理的另一件事,但事實並非如此。我有一個DialogFragment顯示'RetainInstance'設置爲'true',但當我旋轉設備時它會關閉。這不應該發生。 –

+0

你能爲此打開一個問題嗎? – Martijn00