使用Template10的多个视图而不总是显示主页面?

时间:2017-07-27 03:19:02

标签: c# uwp template10 multiple-views

我是T10的新手,并试图学习它。 这是Template 10 Multiple Windows

的后续行动

在'常规'(意为非模板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还显示Main页面(以及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处理。

感谢。

2 个答案:

答案 0 :(得分:2)

  

除了使用OpenAsync显示Main页面(以及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
    }
}

答案 1 :(得分:1)

新代码中已有一个完整的示例,很快就会被推出。它的源代码分支v 1.1.3p

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

VS2017的模板更新最新版本V 1.1.2_vs2017也有相同的样本,您发布的代码或多或少与封面相同,并通过一些调整使其适用于T10 < / p>