I found axnull's answer most helpful, because it allows setting the theme while the app is running. After more than a good afternoon's work, I was able to set the app's theme on the fly and keep it in memory for next startup, giving the user control through a  ToggleButton.
First, I made a settings class with a Theme property that automatically stores the current setting:
AppSettings.cs
class AppSettings
{
   public const ElementTheme DEFAULTTHEME = ElementTheme.Light;
   public const ElementTheme NONDEFLTHEME = ElementTheme.Dark;
   const string KEY_THEME = "appColourMode";
   static ApplicationDataContainer LOCALSETTINGS = ApplicationData.Current.LocalSettings;
   /// <summary>
   /// Gets or sets the current app colour setting from memory (light or dark mode).
   /// </summary>
   public static ElementTheme Theme {
      get {
         // Never set: default theme
         if (LOCALSETTINGS.Values[KEY_THEME] == null)
         {
            LOCALSETTINGS.Values[KEY_THEME] = (int)DEFAULTTHEME;
            return DEFAULTTHEME;
         }
         // Previously set to default theme
         else if ((int)LOCALSETTINGS.Values[KEY_THEME] == (int)DEFAULTTHEME)
            return DEFAULTTHEME;
         // Previously set to non-default theme
         else
            return NONDEFLTHEME;
      }
      set {
         // Error check
         if (value == ElementTheme.Default)
            throw new System.Exception("Only set the theme to light or dark mode!");
         // Never set
         else if (LOCALSETTINGS.Values[KEY_THEME] == null)
            LOCALSETTINGS.Values[KEY_THEME] = (int)value;
         // No change
         else if ((int)value == (int)LOCALSETTINGS.Values[KEY_THEME])
            return;
         // Change
         else
            LOCALSETTINGS.Values[KEY_THEME] = (int)value;
      }
   }
}
Then, in the page constructor, added the following code:
MainPage.xaml.cs
  public MainPage()
  {
     this.InitializeComponent();
     // Set theme for window root
     FrameworkElement root = (FrameworkElement)Window.Current.Content;
     root.RequestedTheme = AppSettings.Theme;
     SetThemeToggle(AppSettings.Theme);
  }
This sets the theme according to the previous selection in app memory, and sets the toggle to match.
The following method gets called when the page loads:
MainPage.xaml.cs
  /// <summary>
  /// Set the theme toggle to the correct position (off for the default theme, and on for the non-default).
  /// </summary>
  private void SetThemeToggle(ElementTheme theme)
  {
     if (theme == AppSettings.DEFAULTTHEME)
        tglAppTheme.IsOn = false;
     else
        tglAppTheme.IsOn = true;
  }
And this handles the toggle's being switched:
MainPage.xaml.cs
  /// <summary>
  /// Switch the app's theme between light mode and dark mode, and save that setting.
  /// </summary>
  private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e)
  {
     FrameworkElement window = (FrameworkElement)Window.Current.Content;
     if (((ToggleSwitch)sender).IsOn)
     {
        AppSettings.Theme = AppSettings.NONDEFLTHEME;
        window.RequestedTheme = AppSettings.NONDEFLTHEME;
     }
     else
     {
        AppSettings.Theme = AppSettings.DEFAULTTHEME;
        window.RequestedTheme = AppSettings.DEFAULTTHEME;
     }
  }
All the above code being created for the following ToggleButton switch:
MainPage.xaml
<ToggleSwitch Name="tglAppTheme"
              Header="Theme"
              OffContent="Light"
              OnContent="Dark"
              IsOn="False"
              Toggled="ToggleSwitch_Toggled" />
This setup is simple enough, and can hopefully save someone the grunt work.