65.9K
CodeProject 正在变化。 阅读更多。
Home

编程 Windows 10 桌面:UWP 焦点(第 6 章)

starIconstarIconstarIconstarIconstarIcon

5.00/5 (7投票s)

2017 年 11 月 28 日

CPOL

11分钟阅读

viewsIcon

14429

downloadIcon

390

UWP 入门(从 WinForm 迁移) 第 6 章 为 DailyJournal 中的多个条目以编程方式添加选项卡(Pivot)(包含 CommandBar 和 Menu 概念)

引言

我正在继续尝试讲述 UWP 范式下的桌面开发故事。

您可以在以下文章中阅读故事的开篇。

编程 Windows 10:UWP 焦点(第 1 部分,共 N 部分)[^]

编程 Windows 10:UWP 焦点(第 2 部分,共 N 部分)[^]

编程 Windows 10:UWP 焦点(第 3 部分,共 N 部分)[^]

编程 Windows 10 桌面:UWP 焦点(第 4 部分,共 N 部分)[^]

编程 Windows 10 桌面:UWP 焦点(第 5 部分,共 N 部分)[^]

背景

这个系列正在加速增长。我不知道发生了什么,但它极大地引起了我的注意,而且我实际上对使用 XAML 越来越感兴趣。不过,我可能只是患上了过度书写症(过度书写症 - 维基百科[^])。微笑 | :)

菜单概念:消失 30 年

我们需要为用户提供一种方式来告知应用程序她想要创建一个新的日记条目。过去,微软帮助创造了顶部菜单的概念,其中包含文件、编辑、视图、帮助等特定项(所有这些顶层菜单项仍然存在于 Visual Studio 中)。

菜单并非触屏的最佳选择

我浏览了一下互联网,发现菜单在 UWP 中基本上消失了。您可能想再读一遍这句话。这相当重要,因为我们都与菜单打交道了很长时间。

如果考虑运行在设备(平板电脑(Surface)、手机等)上的应用程序,那么移除菜单是有道理的。

使用触摸屏时,菜单并不是很容易使用。

然而,这在 Windows 桌面上的意义不大。使用鼠标等指向设备时,菜单仍然应该有效。算了。这是新世界。

CommandBar:新菜单

经过一番搜索,我发现了一个名为 `CommandBar` 的东西。

我之所以找到它,是因为我正在查看是否可以添加一个快速快捷键组合,让用户能够创建一个新条目。看起来我们可以为 `CommandBar` 的子元素添加键盘快捷键(`Ctrl-Shift-S` 或其他)。

又来了

我的想法是添加一个 `CommandBar`,其中包含一些按钮,让用户可以激活创建新条目等功能。

从这里开始

我们将从这里开始:一个带有单个按钮的 CommandBar,用于创建新条目。

我将把这个 `CommandBar` 添加到 `Grid` 的顶部,并让它跨越所有列,这样它就成为用户可以激活功能的中心焦点。

寻找示例代码

我的 `CommandBar` XAML 来自以下示例:https://docs.microsoft.com/en-us/windows/uwp/design/input/keyboard-accelerators

大幅修改

但是,请注意,我已经为我们的目的对其进行了大量修改。我之所以提到我从示例开始,是为了让您意识到开发人员经常这样做。最重要的是确保您完全理解您正在使用的示例。

为 Grid 添加新行

我们需要做的第一件事是更新我们的 XAML,通过添加新的 RowDefinition 来为我们的 Grid 添加一个新行。我们需要添加新行,以便将我们的 `CommandBar` XAML 放置在该行中。

这很简单。只需将以下行添加到 `Grid.RowDefinition` 中:

<RowDefinition Height="Auto"/>

 

这将定义总共三行。

CommandBar 现在是第一行

由于 `CommandBar` 将成为 Grid 中的第一行,我们需要更新以前具有 `Grid.Row=”0”` 属性的其他控件,将它们设置为 `Grid.Row=”1”`。这将确保它们显示在 `CommandBar` 的下方。

我已经完成了这项工作,如果您仔细查看下一张图片,您会看到 `Grid.Row` 在适当的位置已更新。

XAML 和代码下载

这是整个更新后的 XAML。您还可以通过下载本文顶部名为 `DailyJournal_v005.zip` 的 zip 文件来下载已修改的代码。

 

<Page
   x:Class="DailyJournal.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:local="using:DailyJournal"
   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   mc:Ignorable="d" Loaded="Page_Loaded">

   <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" >
       <Grid.RowDefinitions >
           <RowDefinition Height="Auto"/>
           <RowDefinition Height="Auto" />
           <RowDefinition Height="*"/>
       </Grid.RowDefinitions>
       <Grid.ColumnDefinitions>
           <ColumnDefinition Width="Auto"/>
           <ColumnDefinition/>
       </Grid.ColumnDefinitions>
       
       <CalendarView HorizontalAlignment="Left" Grid.Row="1" Grid.Column="0" VerticalAlignment="Top"/>
       <ListView Name="EntriesListView" Grid.Row="2" Grid.Column="0"
           HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
       <Pivot x:Name="rootPivot" Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" >
           <PivotItem Header="Entry1">
               <RichEditBox Name="MainRichEdit" Grid.Column="1" Grid.Row="1" Grid.RowSpan="2"
                    HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
           </PivotItem>
           <PivotItem Header="Entry2">
               <RichEditBox Name="MainRichEdit2" Grid.Column="1" Grid.Row="1" Grid.RowSpan="2"
                    HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
           </PivotItem>
       </Pivot>
   </Grid>
</Page>

 

构建并运行(Ctrl+F5)

继续构建并运行应用程序,您会看到它仍然完美运行。

对 XAML 和布局感到惊喜

我认为很有趣的是,在这些更改之后,DailyJournal 仍然运行得非常好,并且所有项的布局仍然正确。我对此感到非常高兴。XAML 之所以如此酷,正是因为这些。等到您看到我们如何轻松地添加 `CommandBar` 和 `AppBarButtons`,您将更加 impressed。我很高兴它运行得如此之好,以及我如何能够轻松地将新的 XAML 元素添加到现有布局中而不破坏一切。

比例间距的魔力

这实际上都是因为我们使用了比例间距项,它们只是填充了提供的区域。由于目前没有第 0 行 - 或者第 0 行不占用任何布局空间 - 一切都会被挤出视图,并继续看起来好像只有两行。

CommandBar 和相关控件

`CommandBar` 是另一个容器,它可以包含一个或多个 `AppBarButton` 控件。`AppBarButton` 是用户实际点击(或触摸)以激活功能的控件。

现在,我们只想添加一个 AppBarButton,允许用户创建一个新的日记条目。这将使我们能够引入最少的 XAML 来使 CommandBar 和相关的 AppBarButton 工作。我喜欢这样工作:添加小块并使其工作。

粘贴 CommandBar XAML。

此时,在结束的 Grid.ColumnDefinitions 之后、CalendarView 控件之前,有一行空行。我们将把 CommandBar 的 XAML 复制到那个位置,它将出现在 Page 的顶部。

 

您可以在下面的图片中看到我们将粘贴粘贴的位置(就在 I 型光标所在的位置):

 

这是 CommandBar 的新 XAML,您可以将其粘贴到该位置。

<CommandBar  Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2">

           <AppBarButton

        x:Name=”CreateNewEntryButton”

               Icon="NewWindow"

               Label="New"

               ToolTipService.ToolTip="New (Ctrl+N)">

           </AppBarButton>

       </CommandBar>


添加后,它将把 `CommandBar` 添加到 Page 的顶部,您将在 DesignView 中看到它。我已单击 `AppBarButton`,以便它在 DesignView 中获得焦点。

 

 

构建并运行(Ctrl+F5)并查看。

 

 

 

它看起来不错,一切都如预期般工作。

按钮图标

我为“新建条目”`AppBarButton` 使用了 `NewWindow` 图标。该图标来自 UWP SDK(软件开发工具包)为您提供的列表。您可以在此处查看所有图标及其名称的列表:https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.symbol

那个省略号 (...) 项似乎有点奇怪。我们没有添加它,但我们免费获得了它。

 

目前,我们的按钮点击时没有任何反应。这很容易解决,所以让我们来做,看看我们是否可以以编程方式创建新的 PivotItem。

为按钮添加功能

在 DesignView 中,只需双击 CreateNewEntryButton,它就会为该按钮生成一个 Click 方法,并将您移动到 MainPage.xaml.cs 中该方法。

思考、尝试、智能感知和互联网搜索

现在,我们可以尝试弄清楚如何将新的 `PivotItem` 和 `RichEditBox` 添加到我们的 `Page`。

经过几分钟的代码编写,在多年的经验和 Visual Studio 的智能感知(代码帮助)的指导下,我弄清楚了 95% 的工作。

遇到瓶颈:StackOverflow 救援

我遇到的一个问题是如何将 RichEditBox 添加到 PivotItem。但是,通过一次快速搜索,我找到了一个 StackOverflow 条目,它指导我找到了解决方案。

以下是您可以添加到 `CreateNewEntryButton_Click` 方法中的代码,使其能够工作。

 PivotItem pi = new PivotItem();

           var entryText = String.Format("Entry{0}",rootPivot.Items.Count+1);

           pi.Header = entryText;

           RichEditBox reb = new RichEditBox();

           reb.HorizontalAlignment = HorizontalAlignment.Stretch;

           reb.VerticalAlignment = VerticalAlignment.Stretch;

           pi.Content = reb;

           rootPivot.Items.Add(pi);

           rootPivot.SelectedIndex = rootPivot.Items.Count - 1;

我在以下代码截图中标注了数字,以便我们可以讨论每一行做了什么。

 

 

注意:以下文本中的数字与前面代码列表快照中的数字相关。

 

  1. 我们需要做的第一件事是以编程方式创建新的 `PivotItem`。XAML 元素命名的对象与我们在代码中处理的对象完全相同,这使得一切都变得更加容易,这真是太棒了。这是 UWP / XAML 架构师的一大胜利。第一行只是创建了一个新的 PivotItem 对象。

    1. 我对这一行代码完全是猜测,智能感知(Visual Studio 的内置代码助手)帮助我完成了。非常容易。

  2. 我在这里使用了 `var` 关键字,它允许编译器决定目标变量的类型。当然,它将是一个字符串,因为我调用了静态 `String.Format()` 方法,以便创建将用于 PivotItem 头的文本。String.Format() 允许我们轻松创建包含各种值的字符串。格式说明符由花括号和一个数字组成(从 0 开始,并在每次向字符串添加格式说明符时递增)。格式说明符将被目标值替换,该目标值也在方法调用中。在我们的例子中,我们的值是从我们的 rootPivot 对象项的计数中获取的。换句话说,我们有一个对我们的 rootPivot 对象(在 XAML 中定义)的引用,并且在该 rootPivot 对象内部,我们找到了一个名为 Items 的集合,其中包含 rootPivot 对象包含的所有对象(嵌套元素)。我们询问它当前项的数量 `Count`,这是它包含的 PivotItems(选项卡)的数量。我们的应用程序最初有 2 个,但随着用户单击按钮,这个数量会增加。我们向 `Count` 加一,因为我们现在正在添加一个。当然,`Count` 是一个整数值,它将被附加到单词“Entry”后面,所以当按钮第一次被点击时,字符串值将是“Entry3”。这将是我们的新 PivotItem 的第一个头的标题。每次都会递增计数器,字符串将这样形成。

  3. 我们将新的 `PivotItem` 命名为 `pi`,现在我们可以使用此行轻松地将其 Header 文本设置为我们生成的值。

  4. 对于我们创建的每个 `PivotItem`,我们都希望创建一个新的 `RichEditBox`,这就是这行代码的作用。

  5. 这两行非常相似且简单,它们只获取一个数字。在这里,我们将 `RichEditBox` 设置为 `Stretch`(拉伸)以填充 `PivotItem` 提供的可用区域(垂直和水平)。这样,`RichEditBox` 在每个选项卡上都会尽可能大。

  6. 我们需要将 `RichEditBox` 添加到 `PivotItem` 中,以便 `PivotItem` 可以包含 `RichEditBox`。这与我们创建 XAML 时所做的相同。但是,要以编程方式做到这一点,我们必须将 `pi.Content` 设置为我们刚刚创建的新 `RichEditBox`。现在 `reb` 是 `pi` 内容的一部分,它将管理并显示它。

  7. 最后,我们需要将新的 `PivotItem`(包含 `RichEditBox`)添加到我们的外部 `rootPivot`。我们只需将新的 `PivotItem` 添加到 `rootPivot` 的名为 `Items` 的项集合中即可。要添加项,我们调用 `Add()` 方法并将 `pi`(`PivotItem`)传递进去。一切真的很简单。

  8. 添加新的 `PivotItem` 和 `RichEditBox` 后,我们希望应用程序自动选择它,我们可以通过简单地将当前选定的索引设置为最后一个添加的项 - 我们刚刚添加的那个。

 

就是这样。现在您可以运行应用程序并单击“创建新”按钮,每次都会添加一个新的日记条目,并带有一个自动生成的唯一标题。

获取代码下载

如果您一直关注,现在就可以构建并运行它(Ctrl+F5),或者从本文顶部下载 `DailyJournal_v006.zip` 来尝试一下。您可以添加大量 PivotItems(选项卡)。如果添加太多以至于无法全部显示,应用程序将通过添加允许您左右移动的“箭头”来自动处理。

启动它并开始添加 PivotItems。它很酷,这个东西开始感觉像一个真正的应用程序了。

 

添加其他功能时出现功能需求

下一篇文章将从这里继续

现在我们可以轻松添加条目,我们立即认识到我们需要一种方法来

  • 删除条目

  • 保存与条目相关的文本

 

我们将在下次添加这些功能。希望您喜欢本章并有所收获。

历史

2017-11-28:文章首次发布。

© . All rights reserved.