Hi,
I have a registration flow that has 10 or more steps each one being its own view with a viewmodel. Each of the steps should be happening on a SINGLE page. That's why I decided to use the RegistrationViews ControlTemplate and replace it with the new instance of the next steps view on clicking the "Next step" button at the bottom of each subview.
Here is my RegistrationPage.xaml
:
<?xml version="1.0" encoding="UTF-8" ?> <rxui:ReactiveContentPage x:Class="my.Pages.RegistrationPage" xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:effects="clr-namespace:my.Effects" xmlns:extensions="clr-namespace:my.Extensions" xmlns:pvm="clr-namespace:my.PageViewModels" xmlns:rxui="clr-namespace:ReactiveUI.XamForms;assembly=ReactiveUI.XamForms" xmlns:theme="clr-namespace:my.Theme" x:TypeArguments="pvm:RegistrationPageViewModel" BackgroundColor="{x:Static theme:Colors.AppBackground}"> <ContentPage.Content> <Grid effects:SafeAreaEffect.SafeAreas="Bottom" RowSpacing="0"> <Image Grid.RowSpan="2" Aspect="AspectFit" HorizontalOptions="Fill" Source="{extensions:ImageEmbeddedResource my.EmbeddedResources.header_background.png}" VerticalOptions="StartAndExpand" /> <views:RegistrationView x:Name="RegistrationView" NavigateToRegistrationTemplate="{Binding NextPage}" /> </Grid> </ContentPage.Content> </rxui:ReactiveContentPage>
RegistrationView has a custom property called NavigateToRegistrationTemplate. This property should be set in the child viewmodel (f.i. RegistrationClubSelectionView) on button click initialising the push of the next step/control template .
This is how it looks like in my first steps viewmodel:
public class RegistrationClubSelectionViewViewModel : ContentBaseViewModel { public ReactiveCommand<Unit, Unit> SelectedClubButtonClickedCommand { get; private set; } [Reactive] public RegistrationTemplateType NextPage { get; private set; } public RegistrationClubSelectionViewViewModel() : base(null) { SelectedClubButtonClickedCommand = ReactiveCommand.Create(() => { NextPage = RegistrationTemplateType.TEAMSELECTION; }); }
Now I was hopping that setting NextPage would bind it it to <views:RegistrationView x:Name="RegistrationView" NavigateToRegistrationTemplate="{TemplateBinding NextPage}" />
on my RegistrationPage.xaml.
My RegistrationView.cs look like this (It is just a .cs file, no viewmodel or XAML):
using my.PageViewModels; using my.Views.Registration; using ReactiveUI.XamForms; using Xamarin.Forms; using my.Enums.NavigationEnums; namespace my.Views.Registration { public class RegistrationView : ContentView { #region Properties public static BindableProperty NavigateToRegistrationTemplateProperty = BindableProperty.Create( nameof(NavigateToRegistrationTemplateProperty), typeof(RegistrationTemplateType), typeof(RegistrationView), propertyChanged: OnRegistrationTemplateChanged, defaultBindingMode: BindingMode.TwoWay); public RegistrationTemplateType NavigateToRegistrationTemplate { get => (RegistrationTemplateType)GetValue(NavigateToRegistrationTemplateProperty); set => SetValue(NavigateToRegistrationTemplateProperty, value); } private readonly ControlTemplate clubSelectionTemplate = new ControlTemplate(typeof(RegistrationClubSelectionView)); private readonly ControlTemplate teamSelectionTemplate = new ControlTemplate(typeof(RegistrationTeamSelectionView)); #endregion #region Initialisation public RegistrationView() { ControlTemplate = clubSelectionTemplate; } #endregion #region Private methods private static void OnRegistrationTemplateChanged(BindableObject bindable, object oldValue, object newValue) { if (!(bindable is RegistrationView view)) { return; } SelectControlTemplate(view); } private static void SelectControlTemplate(RegistrationView view) { switch (view.NavigateToRegistrationTemplate) { case RegistrationTemplateType.CLUBSELECTION: view.ControlTemplate = view.clubSelectionTemplate; break; case RegistrationTemplateType.TEAMSELECTION: view.ControlTemplate = view.teamSelectionTemplate; break; -> MORE TO COME } } #endregion } }
But propertyChanged: OnRegistrationTemplateChanged
of NavigateToRegistrationTemplateProperty
is never triggered. How can I achieve to bind a childs/control template viewmodel property to the parent property. I tried NavigateToRegistrationTemplate="{TemplateBinding NextPage}"
, too. To me the under the hood RegistrationPage.xaml structure would look like this:
<views:RegistrationView x:Name="RegistrationView" NavigateToRegistrationTemplate="{Binding NextPage}"> <views:RegistrationView.ControlTemplate> <views:RegistrationClubSelectionView /> </views:RegistrationView.ControlTemplate> </views:RegistrationView>-->