使用 ApplicationView 显示多个视图

通过让他们在单独的窗口中查看应用的独立部分,帮助用户提高工作效率。 为应用创建多个窗口时,每个窗口的行为都是独立的。 任务栏分别显示每个窗口。 用户可以独立移动、调整大小、显示和隐藏应用窗口,并且可以在应用窗口之间切换,就像它们是单独的应用一样。 每个窗口在其自己的线程中运行。

重要 APIApplicationViewSwitcherCreateNewView

什么是视图?

应用视图是线程与用于显示内容的窗口之间的 1:1 对应关系。 它由 Windows.ApplicationModel.Core.CoreApplicationView 对象表示。

视图由 CoreApplication 对象管理。 调用 CoreApplication.CreateNewView 以创建 CoreApplicationView 对象。 CoreApplicationView 汇集了 CoreWindowCoreDispatcher(存储在 CoreWindowDispatcher 属性中)。 可以将 CoreApplicationView 视为 Windows 运行时用来与核心 Windows 系统交互的对象。

通常不会直接与 CoreApplicationView交互。 相反,Windows 运行时在 Windows.UI.ViewManagement 命名空间中提供 ApplicationView 类。 此类提供应用与窗口系统交互时使用的属性、方法和事件。 若要使用 ApplicationView,请调用静态 ApplicationView.GetForCurrentView 方法,该方法获取绑定到当前 CoreApplicationView 线程的 ApplicationView 实例。

同样,XAML 框架将 CoreWindow 对象包装在 Windows.UI.XAML.Window 对象中。 在 XAML 应用中,通常与 Window 对象交互,而不是直接使用 CoreWindow

显示新视图

虽然每个应用布局都是唯一的,但我们建议在可预测的位置包括“新建窗口”按钮,例如可以在新窗口中打开的内容的右上角。 另请考虑包括上下文菜单选项以“在新窗口中打开”。

让我们看看创建新视图的步骤。 此时,新的视图将启动以响应按钮的点击。

private async void Button_Click(object sender, RoutedEventArgs e)
{
    CoreApplicationView newView = CoreApplication.CreateNewView();
    int newViewId = 0;
    await newView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        Frame frame = new Frame();
        frame.Navigate(typeof(SecondaryPage), null);   
        Window.Current.Content = frame;
        // You have to activate the window in order to show it later.
        Window.Current.Activate();

        newViewId = ApplicationView.GetForCurrentView().Id;
    });
    bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId);
}

显示新视图

  1. 调用 CoreApplication.CreateNewView 为视图内容创建新窗口和线程。

    CoreApplicationView newView = CoreApplication.CreateNewView();
    
  2. 跟踪新视图的 ID。 稍后将使用此视图显示视图。

    你可能想要考虑将一些基础结构构建到应用中,以帮助跟踪所创建的视图。 有关示例,请参阅MultipleViews 示例中的ViewLifetimeControl类。

    int newViewId = 0;
    
  3. 在新线程中填充窗口。

    可以使用 CoreDispatcher.RunAsync 方法在新视图的 UI 线程上计划工作。 使用 lambda 表达式 将函数作为参数传递给 RunAsync 方法。 在 lambda 函数中执行的工作发生在新视图的线程上。

    在 XAML 中,通常向窗口的内容属性添加框架,然后将框架导航到在其中定义应用内容的 XAML 页面。 有关框架和页面的更多信息,请参阅 两个页面之间的点对点导航

    填充新 窗口 后,必须调用 WindowActivate 方法,以便稍后显示 窗口 。 此工作发生在新视图的线程上,因此新的 窗口 被激活。

    最后,获取新视图的 ID,以便稍后显示视图。 同样,此工作在新视图的线程上,因此 ApplicationView.GetForCurrentView 获取新视图的 ID

    await newView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        Frame frame = new Frame();
        frame.Navigate(typeof(SecondaryPage), null);   
        Window.Current.Content = frame;
        // You have to activate the window in order to show it later.
        Window.Current.Activate();
    
        newViewId = ApplicationView.GetForCurrentView().Id;
    });
    
  4. 通过调用 ApplicationViewSwitcher.TryShowAsStandaloneAsync来显示新视图。

    创建新视图后,可以通过调用 ApplicationViewSwitcher.TryShowAsStandaloneAsync 方法在新窗口中显示它。 此方法的 viewId 参数是一个整数,用于唯一标识应用中的每个视图。 通过使用 ApplicationView.Id 属性或 ApplicationView.GetApplicationViewIdForWindow 方法,可以检索视图 ID

    bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId);
    

主视图

应用启动时创建的第一个 视图称为主视图。 此视图存储在 CoreApplication.MainView 属性中,其 IsMain 属性为 true。 不创建此视图;它由应用创建。 主视图的线程充当应用的管理器,所有应用激活事件都在此线程上传递。

如果辅助视图处于打开状态,则主视图的窗口可以隐藏(例如,单击窗口标题栏中的关闭(x)按钮,但其线程保持活动状态。 在主视图的 窗口 上调用 关闭 会导致发生 InvalidOperationException。 (使用 Application.Exit 关闭应用。)如果主视图的线程终止,应用将关闭。

辅助视图

其他视图(包括通过调用应用代码中的 CreateNewView 创建的所有视图)都是辅助视图。 主视图和辅助视图都存储在 CoreApplication.Views 集合中。 通常,你会创建辅助视图页面来响应用户操作。 在某些情况下,系统会为应用创建辅助视图。

注释

可以使用 Windows 分配的访问 功能在 展台模式中运行应用。 执行此作时,系统会创建辅助视图,以在锁屏上方显示应用 UI。 不允许应用创建的辅助视图,因此,如果尝试在展台模式下显示自己的辅助视图,则会引发异常。

从一个视图切换到另一个视图

请考虑为用户提供从辅助窗口导航回其父窗口的方法。 为此,请使用 ApplicationViewSwitcher.SwitchAsync 方法。 你需要从正在切换的窗口的线程调用此方法,并传递要切换到的窗口的视图 ID。

await ApplicationViewSwitcher.SwitchAsync(viewIdToShow);

使用 SwitchAsync 时,可以选择是否要关闭初始窗口,并通过指定 ApplicationViewSwitchingOptions 的值将其从任务栏中删除。