MobileBlazorBindings icon indicating copy to clipboard operation
MobileBlazorBindings copied to clipboard

Allow overriding Page.OnBackButtonPressed

Open Dreamescaper opened this issue 4 years ago • 7 comments
trafficstars

I need to block back button under certain conditions, and suggested approach is to override Page.OnBackButtonPressed method. Unfortunately, method override is not something we can add in razor syntax.

As for now I implement it in the following way:

    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender)
        {
            var nativePage = page.NativeControl;
            nativePage.Appearing += (_, _) => XF.Shell.Current.Navigating += Navigating;
            nativePage.Disappearing += (_, _) => XF.Shell.Current.Navigating -= Navigating;
        }
    }

    void Navigating(object sender, XF.ShellNavigatingEventArgs args)
    {
        if (args.CanCancel)
            args.Cancel();
    }

That's quite verbose though, and works only if Shell is used.

So I'm thinking whether it is possible to make it easier somehow. I have an idea to create some MbbPage class, which inherits XF.Page, and exposes this method as event, and use that class instead of XF.Page for Page component. But that would require to created inherited classes for any class which inherits XF.Page, which doesn't sound great.

Any other ideas?

Dreamescaper avatar Jan 11 '21 20:01 Dreamescaper

Hmm ideally these would all be events exposed from Xamarin.Forms. But we could expose the overrides as events from within Mobile Blazor Bindings (which is basically what you propose, but built-in). I wouldn't be opposed to adding these whenever we see fit. This works mostly for virtual methods that are void because event handlers don't compose well if they have return values. (You typically have to devise other solutions such as FooBarEventArgs where you set a return value property.)

Eilon avatar Jan 11 '21 22:01 Eilon

Yeah, I thought about something like BackButtonPressedEventArgs with Cancel method (similar to Shell.Navigating).

But again, with such approach we'll need to do same for each Page descendant (e.g. TabbedPage, ContentPage, FlyoutPage/MasterDetailPage etc.).

We won't be able to add those to Page only, as it won't be inherited automatically.

Dreamescaper avatar Jan 11 '21 22:01 Dreamescaper

If we add an event to the Mobile Blazor Bindings Page why wouldn't it work on derived types?

Eilon avatar Jan 14 '21 18:01 Eilon

So let's say I add this event to some inherited Page class:

public class MbbPage: XF.Page
{
	public event EventHandler<...> OnBackButtonPressedEvent {get;set;}

    protected override bool OnBackButtonPressed()
	{
		// Invoke OnBackButtonPressedEvent , handle result
		return base.OnBackButtonPressed();
	}
}

Now class XF.ContentPage does not have this event, as it inherits XF.Page, therefore I need to create some MbbContentPage. I cannot inherit MbbContentPage from MbbPage, as it won't contain XF.ContentPage parts, so I need to inherit it from XF.ContentPage - and add that override again:

public class MbbContentPage: XF.ContentPage
{
	public event EventHandler<...> OnBackButtonPressedEvent {get;set;}
    protected override bool OnBackButtonPressed() { ... }
}

And I'd need to do that for each XF.Page inherited class. Unless I'm missing something.

Dreamescaper avatar Jan 14 '21 18:01 Dreamescaper

Oh, you probably mean Page Blazor component. That would be inherited by other Page Blazor component indeed, but we need to connect it to XF.Page somehow. And I haven't found any other way to do that apart from OnBackButtonPressed method override.

Dreamescaper avatar Jan 14 '21 18:01 Dreamescaper

Ohhhhhhhhh right I see. Yes I did mean the MBB Element Page, but you're right that we would need a derived XF Page to wire it up. No fun ☹️

Eilon avatar Jan 14 '21 18:01 Eilon

Perhaps the best solution is to get this added to Xamarin.Forms. Otherwise whatever we do in MBB will always have limitations. (But I'm fine if you want to add a solution to MBB for now using one of the previous ideas here.)

Eilon avatar Jan 14 '21 18:01 Eilon