I have ViewModel and DialogFragment for view this VM. In core I show VM in this way
this.ShowViewModel<AnnotationEditViewModel>();
i have this code in AnnotationEditDialogFragment.cs
[Register("AnnotationEditDialogFragment")]
public class AnnotationEditDialogFragment : MvxDialogFragment<AnnotationEditViewModel>
{
...
public override Dialog OnCreateDialog(Bundle savedInstanceState)
{
base.EnsureBindingContextSet(savedInstanceState);
var view = this.BindingInflate(Resource.Layout.text_annotation_dialog_fragment, null);
var titleAnnotationTextView = view.FindViewById<TextViewWithFont>(Resource.Id.titleAnnotationTextView);
var set = this.CreateBindingSet<AnnotationEditFragment, AnnotationEditViewModel>();
set.Bind(this).For(be => be.CanBeSaved).To(vm => vm.CanBeSaved);
set.Apply();
builder = new AlertDialog.Builder(Activity);
LayoutInflater inflater = Activity.LayoutInflater;
builder.SetView(view);
alertDialog = builder.Create();
return alertDialog;
}
...
}
I have request in MainPresenter in Showv method where i can detect this request.
if in MainPresenter i type this code:
var textAnnotationDialogFragment = Activity.FragmentManager.FindFragmentByTag(nameof(AnnotationEditFragment)) as AnnotationEditFragment ?? new AnnotationEditFragment();
textAnnotationDialogFragment.Show(Activity.FragmentManager, nameof(AnnotationEditFragment));
if i type this code for ShowViewModel():
base.Show(request, fragmentRequest);
The issues:
1. Presenter Handled Request approach - ViewModel Null
Using this approach the ViewModel
property of AnnotationEditFragment
is null as no ViewModel
has been set on the fragment as it is being created outside of the normal lifecycle Mvx uses when creating normal MvxFragments
. MvxDialogFragment
follow a different lifecycle.
2. Presenter Unhandled Request approach - No Activity
Using this approach the standard Mvx fragment lifecycle is trying to be executed on the MvxDialogFragment
. Which requires an Activity to be specified to place the fragment into. This is not the approach we want with the MvxDialogFragment
.
Solution:
I believe approach 1 is the closest to getting us a successfully implementation of a working MvxDialogFragment
. All we need to do is make sure the ViewModel runs through it's lifecycle. So in your MainPresenter
make sure to create an instance of the AnnotationEditViewModel
based on the request and assign it to the AnnotationEditFragment
:
protected override void ShowActivity(MvxViewModelRequest request, MvxViewModelRequest fragmentRequest = null)
{
if (request.ViewModelType == typeof(NamesViewModel))
{
var dialog = new AnnotationEditFragment();
var viewModel = Mvx.Resolve<IMvxViewModelLoader>().LoadViewModel(request, null) as AnnotationEditViewModel;
dialog.ViewModel = viewModel;
dialog.Show(Activity.FragmentManager, nameof(AnnotationEditFragment));
return;
}
base.ShowActivity(request, fragmentRequest);
}
IMvxViewModelLoader
is used to make sure the ViewModel is loaded according to the Mvx ViewModel lifecycle standard, CIRS:
- Construction - using IoC for Dependency Injection
- Init() - initialisation of navigation parameters
- ReloadState() - rehydration after tombstoning
- Start() - called when initialisation and rehydration are complete