Navigation

You can navigate between pages (i.e. between root components) using the following extensions API:

INavigation.PushAsync<T>()

where T is the type of the component to create as root of the new page.

For example this is a component that move to second page hosting ChildPageComponent when user click a button:

public class MainPageComponent : RxComponent
{
    public override VisualNode Render()
    {
        return new RxNavigationPage()
        {
            new RxContentPage()
            {
                new RxButton("Move To Page")
                    .VCenter()
                    .HCenter()
                    .OnClick(OpenChildPage)
            }
            .Title("Main Page")
        };
    }

    private async void OpenChildPage()
    {
        await Navigation.PushAsync<ChildPageComponent>();
    }
}

and this is the code implementing the child page with a button to go back

public class ChildPageComponent : RxComponent
{
    public override VisualNode Render()
    {
        return new RxContentPage()
        {
            new RxButton("Back")
                .VCenter()
                .HCenter()
                .OnClick(GoBack)
        }
        .Title("Child Page");
    }

    private async void GoBack()
    {
        await Navigation.PopAsync();
    }
}

Passing data between pages

You can pass parameters to other pages using component Props. Let's modify the main page component from the above sample to hold a state:

public class MainPageComponentState : IState
{
    public int Value { get; set; }
}

public class MainPageComponent : RxComponent<MainPageComponentState>
{
    public override VisualNode Render()
    {
        return new RxNavigationPage()
        {
            new RxContentPage()
            {
                new RxStackLayout()
                {
                    new RxLabel($"Value: {State.Value}")
                        .FontSize(NamedSize.Large),
                    new RxButton("Move To Page")
                        .OnClick(OpenChildPage)
                }
                .VCenter()
                .HCenter()
            }
            .Title("Main Page")
        };
    }

    private async void OpenChildPage()
    {

    }
}

In the OpenChildPage callback we need to open the child page passing current value: we want to edit the value in entry control. Let's change the child page adding a state and a props as the following:

public class ChildPageComponentState : IState
{
    public int Value { get; set; }
}

public class ChildPageComponentProps : IProps
{
    public int InitialValue { get; set; }

    public Action<int> OnValueSet { get; set; }
}

public class ChildPageComponent : RxComponent<ChildPageComponentState, ChildPageComponentProps>
{
    protected override void OnMounted()
    {
        State.Value = Props.InitialValue;

        base.OnMounted();
    }

    public override VisualNode Render()
    {
        return new RxContentPage()
        {
            new RxStackLayout()
            {
                new RxEntry(State.Value.ToString())
                    .OnAfterTextChanged(_=>SetState(s => s.Value = int.Parse(_)))
                    .Keyboard(Keyboard.Numeric),
                new RxButton("Back")
                    .OnClick(GoBack)
            }
            .VCenter()
            .HCenter()
        }
        .Title("Child Page");
    }

    private async void GoBack()
    {
        Props.OnValueSet(State.Value);

        await Navigation.PopAsync();
    }
}

Now the ChildPageComponent has a state and a props: the latter will hold the initial value and a callback action to call when user click the back button.

Finally call the child page setting its props properties:

private async void OpenChildPage()
{
    await Navigation.PushAsync<ChildPageComponent, ChildPageComponentProps>(_=>
    {
        _.InitialValue = State.Value;
        _.OnValueSet = this.OnValueSetFromChilPage;
    });
}

private void OnValueSetFromChilPage(int newValue)
{
    SetState(s => s.Value = newValue);
}

Last updated