To do this, you can use the MvxViewPagerFragmentPresentationAttribute so that the Presenter takes responsibility for displaying the fragments, and you just show the ViewModels by passing the Recipe parameter like any other, but at the moment there are some minor errors.
However, one way to solve this is to have the fragments you want to have in your ViewPager in your ViewPager and load them into Initialize so that you can then refer to them from RecipeDetailActivity :
Using Mvx 5, you can use the new Navigation to show ViewModels. If parts are opened from RecipeListViewModel , then:
public class RecipeDetailViewModelArgs { public RecipeDetailViewModelArgs(RecipeModel recipe) { this.Recipe = recipe; } public RecipeModel Recipe { get; } } public class RecipeListViewModel : MvxViewModel { private readonly IMvxNavigationService navigationService; public RecipeListViewModel(IMvxNavigationService navigationService) { this.navigationService = navigationService; } private async Task SelectRecipe(RecipeModel recipe) { await this.navigationService.Navigate<RecipeDetailViewModel, RecipeDetailViewModelArgs>(new RecipeDetailViewModelArgs(recipe)); } }
Then, in your ViewModel details, you simply cache the recipe, download the ViewModels files (ingredients and flavors) for the children, and set the recipe for them:
public class RecipeDetailViewModel : MvxViewModel<RecipeDetailViewModelArgs> { private readonly IMvxViewModelLoader mvxViewModelLoader; private readonly IMvxJsonConverter jsonConverter; private RecipeModel recipe; public RecipeDetailViewModel(IMvxViewModelLoader mvxViewModelLoader, IMvxJsonConverter jsonConverter) { this.mvxViewModelLoader = mvxViewModelLoader; this.jsonConverter = jsonConverter; } public override void Prepare(RecipeDetailViewModelArgs parameter) { this.recipe = parameter.Recipe; } protected override void SaveStateToBundle(IMvxBundle bundle) { base.SaveStateToBundle(bundle); bundle.Data["RecipeKey"] = this.jsonConverter.SerializeObject(this.recipe); } protected override void ReloadFromBundle(IMvxBundle state) { base.ReloadFromBundle(state); this.recipe = this.jsonConverter.DeserializeObject<RecipeModel>(state.Data["RecipeKey"]); } public override async Task Initialize() { await base.Initialize(); this.InitializeChildrenViewModels(); } public RecipeFlavoursViewModel FlavoursViewModel { get; private set; } public RecipeIngridientsViewModel IngredientsViewModel { get; private set; } protected virtual void InitializeChildrenViewModels() {
Then, when you load the ViewPager , you can use another constructor MvxViewPagerFragmentInfo => public MvxViewPagerFragmentInfo (string title, string tag, Type fragmentType, IMvxViewModel viewModel, object parameterValuesObject = null) so that you can preload previously loaded ViewModels models:
this.viewPager = view.FindViewById<ViewPager>(Resource.Id.viewPagerDetails); if (viewPager != null) { var fragments = new List<MvxViewPagerFragmentInfo>(); fragments.Add(new MvxViewPagerFragmentInfo("Ingredients", "RecipeIngridientsViewModelTag", typeof(RecipeIngridientsView), this.ViewModel.IngridientsViewModel)); fragments.Add(new MvxViewPagerFragmentInfo("Flavours", "RecipeFlavoursViewModelTag", typeof(RecipeFlavoursView), this.ViewModel.FlavoursViewModel)); this.viewPager.Adapter = new MvxFragmentPagerAdapter(this.Activity, this.ChildFragmentManager, fragments); }
What is it.
By the way, if you do not want to use navigation or you do not use Mvx 5.x, then you simply initialize the child ViewModels in the void Start() method.
And in order to conclude that you want to change the values ββof your Recipe in children, one simple way is to initialize Singleton with Recipe , and then just enter Singleton in the constructors so that you always have the link in the same Recipe, and you donβt need to pass the Recipe object back and forth to these ViewModels and merge the changes made from each of them. Additional Information at MvvmCross: Access Models by Link
E.I.V.