2

我是 T10 的新手,正在努力学习它。这是模板 10 多个窗口的后续内容

在“常规”(意思是非模板 10)UWP 应用程序中,我学会了做这样的事情(作为一个简短的例子)以支持多个视图:

public App() { InitializeComponent(); Suspending += OnSuspending; }

readonly List<CoreDispatcher> _dispatchers = new List<CoreDispatcher>();
protected override async void OnLaunched(LaunchActivatedEventArgs e)
{
    Frame rootFrame = Window.Current.Content as Frame;
    if (rootFrame == null) 
    {
        rootFrame = new Frame();
        rootFrame.NavigationFailed += OnNavigationFailed;

        Window.Current.Content = rootFrame;
        if (rootFrame.Content == null)
        {
            rootFrame.Navigate(typeof(MainPage), e.Arguments);
        }

        Window.Current.Activate();
        _dispatchers.Add(CoreWindow.GetForCurrentThread().Dispatcher);
    }
    else 
    {
        var view = CoreApplication.CreateNewView();
        int windowId = 0;
        await view.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {
            windowId = ApplicationView.GetApplicationViewIdForWindow(CoreWindow.GetForCurrentThread());
            var frame = new Frame();
            frame.Navigate(typeof(MainPage), null);
            Window.Current.Content = frame;
            Window.Current.Activate();
            ApplicationView.GetForCurrentView().Consolidated += View_Consolidated;
        });

        await _dispatchers[_dispatchers.Count - 1].RunAsync
        (
            CoreDispatcherPriority.Normal, async () => { var _ = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(windowId); }
        );
        _dispatchers.Add(view.Dispatcher);
    }
}

private void View_Consolidated(ApplicationView sender, ApplicationViewConsolidatedEventArgs args)
{
    _dispatchers.Remove(CoreWindow.GetForCurrentThread().Dispatcher);
    ApplicationView.GetForCurrentView().Consolidated -= View_Consolidated;
}

现在:我如何使用 Template10 做到这一点?我查看了https://github.com/Windows-XAML/Template10/wiki/Multiple-Views示例,但无法弄清楚。更具体地说,我想在使用协议激活(使用汉堡模板)时转到特定页面。这是我到目前为止提出的:

public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs args)
{
    var protocolArgs = args as ProtocolActivatedEventArgs;
    if (protocolArgs != null && protocolArgs.Uri != null)
    {
        await NavigationService.OpenAsync(typeof(Views.DetailPage)); // protocol activation
    }
    else
    {
        await NavigationService.NavigateAsync(typeof(Views.MainPage)); // regular activation
    }
}

这工作除了主页面也与 OpenAsync 一起显示(连同 DetailPage)。使用上面描述的“常规”UWP 方法我没有问题。我怎样才能让它按我的意愿工作?我敢肯定这很简单。

到目前为止,我喜欢 T10 - 感谢 Jerry 和团队的贡献。

编辑更多细节

根据以下建议,我将代码(在 App.xaml.cs 中)更改为:

public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs args)
{
    var protocolArgs = args as ProtocolActivatedEventArgs;
    if (protocolArgs != null)
    {
        var pageName = protocolArgs.Uri.AbsolutePath;
        if (!string.IsNullOrEmpty(pageName))
        {
            string pageId = protocolArgs.Uri.LocalPath;
            var pageQuery = protocolArgs.Uri.Query;
            // Here would navigate to the page specified by "pageId"... as an example:
            if (pageId == "foo")
                await NavigationService.OpenAsync(typeof(Views.FooPage), null, pageQuery);
            else if (pageId == "bar")
                await NavigationService.OpenAsync(typeof(Views.BarPage), null, pageQuery);
            else
                await NavigationService.NavigateAsync(typeof(Views.MainPage));
        }
    }
    else
    {
        await NavigationService.NavigateAsync(typeof(Views.MainPage));
    }

}

和:

public override UIElement CreateRootElement(IActivatedEventArgs args)
{
    var service = NavigationServiceFactory(BackButton.Attach, ExistingContent.Exclude);

    var protocolArgs = args as ProtocolActivatedEventArgs;
    var pageName = protocolArgs?.Uri.AbsolutePath;
    if (!string.IsNullOrEmpty(pageName))
    {
        return new Frame();  <<---------- WRONG?
    }

    return new ModalDialog
    {
        DisableBackButtonWhenModal = true,
        Content = new Views.Shell(service),
        ModalContent = new Views.Busy(),
    };

}

现在,我有一个空白表单,在使用协议激活时也会显示(不再是 Sunteen 指出的 Shell 表单),因为(我认为)上面标记为“错误”的行。我的理解是需要执行 CreateRootElement,但是当应用程序被协议激活时,我没有/不想显示根框架;但 CreateRootElement 必须返回一些东西。正如您在我的示例中看到的那样,它与 MultipleViews 示例并不完全相同,因为该示例始终具有根框架。注意:此外,我认为对于 T10,我不应该/不能使用 Sunteen 建议的直接导航:导航必须全部由 T10 处理。

谢谢。

4

2 回答 2

2

这工作除了主页面也与 OpenAsync 一起显示(与 DetailPage 一起)

我想你的意思是Shell.xaml页面也显示了。这是因为当前NavigationService属于没有页面的框架Shell,该Shell页面在导航之前已经通过CreateRootElement方法创建。

使用协议激活时我想转到特定页面(使用汉堡模板)

为了满足您的要求,我建议您不要破坏项目中的导航结构,而是为协议启动的特殊场景创建一个新框架。例如:

public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs args)
{
    // TODO: add your long-running task here    
    var protocolArgs = args as ProtocolActivatedEventArgs;
    if (protocolArgs != null && protocolArgs.Uri != null)
    {
        Frame newframe = new Frame();
        newframe.Navigate(typeof(Views.DetailPage));
        Window.Current.Content = newframe; // protocol activation
    }
    else
    {
        await NavigationService.NavigateAsync(typeof(Views.MainPage)); // regular activation
    }
}
于 2017-07-28T08:20:42.803 回答
1

即将推出的较新代码中已经有一个完整的示例。它在源分支下 v 1.1.3p

https://github.com/Windows-XAML/Template10/tree/version_1.1.13p/Samples/MultipleViews/ViewModels

最新版本 V 1.1.2_vs2017 是 VS2017 的模板更新也具有相同的示例,您发布的代码在幕后或多或少相同,并进行了一些调整以使其与 T10 正常工作

于 2017-07-30T03:04:23.737 回答