c# - 使用 Template10 的多个 View 而不总是显示主页?

标签 c# uwp template10 multiple-views

我是 T10 新手,正在尝试学习它。 这是 Template 10 Multiple Windows 的后续内容

在“常规”(即非 Template10)UWP 应用程序中,我学会了执行类似的操作(作为一个简短的示例)以支持多个 View :

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样本但无法弄清楚。更具体地说,我想在使用协议(protocol)激活(使用汉堡模板)时转到特定页面。 这是我到目前为止所想到的:

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

除了主页面(与 DetailPage 一起)也与 OpenAsync 一起显示之外,此方法有效。使用上述“常规”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(),
    };

}

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

谢谢。

最佳答案

This works EXCEPT that the Main page is also displayed (along with the DetailPage) with the OpenAsync

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

I want to go to a specific page when using protocol activation (using Hamburger template)

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

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

关于c# - 使用 Template10 的多个 View 而不总是显示主页?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45340770/

相关文章:

c# - UWP Windows 10 应用程序中页面/ View 的通用基类

mvvm - 在UWP中,只读的计算属性未在View中更新

mvvm - MVVM,UWP和模板10- View 技术的模型独立性

c# - ASP.NET Controller 操作返回状态代码 200,但 EndRequest 将其设置为 204 (NoContent)

c# - 不使用 Visual Studio 运行 ASP/C#

C# 在不使用数据库的情况下在用户 session 之间持久化对象

c# - 如何使用默认输出设备作为通过AudioGraph录制音频的来源?

c# - 如何在 UWP 应用程序中检查 Windows 10 操作系统版本以消除 WACK 测试失败?

c# - 如何跟踪循环中完成了多少异步任务?

c++ - 如何从 Qt 应用程序访问 UWP API?