Search code examples
c#inheritancexamarin.formsderived-classcontent-pages

How to inherit from a Xamarin Forms base class Page with views in it?


This is driving me nuts. I'm trying to inherit from a base SettingsPage I made, and it's not working, and I can't find a single example anywhere of how to do it. All the examples I've found involve inheriting viewmodels, and other non-visual elements. In particular I'm not sure what you do with the "Content=" in the derived page, since the base page already sets "Content=". The MS doco on inheritance says that you don't inherit the constructor, but that you can inherit from it using :base().

I've put together a colour-scheme picker (which extends on amporis.xamarin.forms.colorpicker), which I want to use as my base for other settings pages (in apps where I want the colour-scheme picker and other settings as well). I have a class library CSettings, for which CSettingsPage loads fine if loaded directly (which includes Content=SettingsGrid, which everything is loaded into to begin with) - everything is "public". I then have a TestBed app, and trying to create a TBSettingsPage. At the top I have

namespace TestBed {
    public class TBSettingsPage : CSettingsPage {...

(and I've referenced the DLL of course), and I've tried the following 3 variations with the constructor...

public TBSettingsPage():base() {}
public TBSettingsPage():base() { Content=SettingsGrid; }
public TBSettingsPage() { Content=SettingsGrid; }

Every time I get...

"Exception thrown: 'System.Runtime.InteropServices.COMException' in Xamarin.Forms.Platform.UAP.dll Error HRESULT E_FAIL has been returned from a call to a COM component." at the Xamarin.Forms init.

...which isn't a very helpful error message. It basically says "that's not right" without telling me what's not right nor how to fix it (Googling it comes up with a whole variety of situations, none of which apply to what I'm trying to do). :-(

Can anyone tell me how to derive from a BasePage that has view in it already? (I saw a tip about making it not visible until the page has been constructed, then make it visible, but that didn't help). Or point me to an example somewhere which implements such a thing?

Note: my UI is in C#, not XAML. Also this is in UWP, if that's relevant.

thanks, Donald.

As requested, here is the code from OnLaunched

protected override void OnLaunched(LaunchActivatedEventArgs e) {

        Frame rootFrame = Window.Current.Content as Frame;

        // Do not repeat app initialization when the Window already has content,
        // just ensure that the window is active
        if (rootFrame == null)
        {
            // Create a Frame to act as the navigation context and navigate to the first page
            rootFrame = new Frame();

            rootFrame.NavigationFailed += OnNavigationFailed;

            Xamarin.Forms.Forms.Init(e);

            if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
            {
                //TODO: Load state from previously suspended application
            }

            // Place the frame in the current Window
            Window.Current.Content = rootFrame;
        }

        if (rootFrame.Content == null)
        {
            // When the navigation stack isn't restored navigate to the first page,
            // configuring the new page by passing required information as a navigation
            // parameter
            rootFrame.Navigate(typeof(MainPage), e.Arguments);
        }
        // Ensure the current window is active
        Window.Current.Activate();
    }

Solution

  • So I ended up finding out this was all due to a bug in UWP giving me a red herring - see https://github.com/xamarin/Xamarin.Forms/issues/9335. The correct syntax is the first one I said - i.e. public TBSettingsPage():base() {} - but the UWP bug was preventing me from seeing it was correct (because my app was still crashing). Thankfully this bug is now being worked on, and I can continue coding now that I know the correct syntax. :-)