如何用shell开副window?

How to open a secondary window with a shell?

我试图将在模板 10 on GitHub 中实现 shell 的说明改编为辅助 window 中的 shell,但它不起作用。

此代码:

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));
    });

得到这个异常:

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 的构造如下:

public static HamburgerMenu HamburgerMenu => Instance.EmulatorHamburgerMenu;

    public MySecondaryShell(INavigationService navigationService)
    {
        this.InitializeComponent();
        HamburgerMenu.NavigationService = navigationService;
    }

当我打开主 window 及其 shell 时,我创建了 shell 对象,然后将 NavigationService 分配给它。

但是当我打开辅助 window 时,我只是调用 NavigationService.OpenAsync 并将 typeof(MySecondaryShell) 作为参数。是shell中NavigationService没有设置正确的问题吗? (通过阅读 中的 Template10 代码,我看不到设置 NavigationService 的位置)。

我应该如何打开 shell 作为辅助 window?

How should I open a shell as a secondary window?

问题是您没有将 navigationService 传递给 MySecondaryShell。然后 MySecondaryShell 将在没有 navigationService 的情况下初始化失败。你可以让你的 shell 像下面这样。

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;
    }
}

用法

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));
    });

});