I tried to adapt the instructions for implementing a shell in Template10 on GitHub to a shell in a secondary window, but it is not working.
This code:
await DispatcherWrapper.Current().DispatchAsync(async () =>
{
//The next line gets the exception
var control = await BootStrapper.Current.NavigationService.OpenAsync(
typeof(MySecondaryShell), null, "My Secondary Function");
control.Released += Control_Released;
BootStrapper.Current.NavigationService.Navigate(typeof(MySecondaryPage));
});
gets this exception:
E VUI 1808 16:12:27.203 D:\SVN_Trunk\Source\Uwp\Gui\UwpMain\ViewModels\MyPrimaryShellViewModel.cs.275.MyFunction System.NullReferenceException: Object reference not set to an instance of an object. at Uwp.Main.UwpMain_XamlTypeInfo.XamlUserType.ActivateInstance() at Windows.UI.Xaml.Controls.Frame.Navigate(Type sourcePageType, Object parameter, NavigationTransitionInfo infoOverride) at Template10.Services.NavigationService.FrameFacade.Navigate(Type page, Object parameter, NavigationTransitionInfo infoOverride) at Template10.Services.NavigationService.NavigationService.d__34.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Template10.Services.NavigationService.NavigationService.Navigate(Type page, Object parameter, NavigationTransitionInfo infoOverride) at Template10.Services.ViewService.ViewService.<>c__DisplayClass1_0.<b__0>d.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Template10.Services.ViewService.ViewService.d__1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at Uwp.Main.ViewModels.MyPrimaryShellViewModel.<>c__DisplayClass63_0.<b__0>d.MoveNext()
MySecondaryShell is constructed like this:
public static HamburgerMenu HamburgerMenu => Instance.EmulatorHamburgerMenu;
public MySecondaryShell(INavigationService navigationService)
{
this.InitializeComponent();
HamburgerMenu.NavigationService = navigationService;
}
When I open the primary window with its shell, I create the shell object and then assign the NavigationService to it.
But when I'm opening a secondary window, I just call NavigationService.OpenAsync with the typeof(MySecondaryShell) as a parameter. Is the problem that the NavigationService is not set correctly in the shell? (From reading the Template10 code in my last question, I could not see where the NavigationService is set).
How should I open a shell as a secondary window?
How should I open a shell as a secondary window?
The problem is you have not passed navigationService to MySecondaryShell
. And then MySecondaryShell
will fail initialization without navigationService. You could make your shell like following.
public sealed partial class MyShell : Page
{
public static MyShell Instance { get; set; }
public static HamburgerMenu HamburgerMenu => Instance.MyHamburgerMenu;
Services.SettingsServices.SettingsService _settings;
public MyShell()
{
Instance = this;
this.InitializeComponent();
_settings = Services.SettingsServices.SettingsService.Instance;
var service = BootStrapper.Current.NavigationServiceFactory(BootStrapper.BackButton.Attach, BootStrapper.ExistingContent.Exclude);
SetNavigationService(service);
}
public void SetNavigationService(INavigationService navigationService)
{
MyHamburgerMenu.NavigationService = navigationService;
HamburgerMenu.RefreshStyles(_settings.AppTheme, true);
HamburgerMenu.IsFullScreen = _settings.IsFullScreen;
HamburgerMenu.HamburgerButtonVisibility = _settings.ShowHamburgerButton ? Visibility.Visible : Visibility.Collapsed;
}
}
Usage
await DispatcherWrapper.Current().DispatchAsync(async () =>
{
var control = await BootStrapper.Current.NavigationService.OpenAsync(typeof(Views.MyShell), null, Guid.NewGuid().ToString());
await control.CoreDispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
Views.MyShell.HamburgerMenu.NavigationService.Navigate(typeof(Views.TestPage));
});
});