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

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

starIconstarIconstarIconstarIconstarIcon

5.00/5 (7投票s)

2017 年 11 月 27 日

CPOL

12分钟阅读

viewsIcon

14046

downloadIcon

211

UWP 入门(从 WinForm 迁移) 第 4 章 添加 Windows 控件(构建 DailyJournal 应用程序)

引言

这是我继续讲述 UWP 范式下桌面开发(以及检验其可行性)的故事的努力。

请从第一部分开始,查看其他条目

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

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

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

背景

正如上一章(关于“兔子洞”的章节)中所承诺的,让我们开始为我们的应用程序添加一些控件并编写一些代码。

注意:我们正在创建的 DailyJournal 应用程序的更多细节请参阅本文的第 3 部分。您也可以获取包含应用程序图标的 DailyJournal 项目的步骤 1。

请在 Visual Studio 中打开 DailyJournal 项目。您可以在我上一篇文章(第 3 部分)的开头找到我们将要开始使用的代码。

考虑基本布局

我们需要稍微考虑一下我们的布局,正如我在上一章向您展示的,我们的主页面基本上会按照以下方式布局

 

考虑到这一点,以及项目模板最初向我们的主页面添加了一个 Grid XAML 元素的事实,我们将修改 Grid 元素,以便它能为我们提供该布局。

我们通过向 Grid 元素添加一些额外的定义来实现这一点。

修改 Grid 布局

为了开始,我将从 Microsoft 的 UWP 文档中复制一些示例代码,并将其粘贴到我的 MainPage.xaml 中。

这是我们应该如何做。

看看当前的 Grid 元素。

它现在只是一个单独的标签。但是,我们需要它打开,以便它是一个容器类型的标签。

请注意,该元素目前带有结束的斜杠 /。要进行我们想要的更改,请继续

  1. 删除那个斜杠 /

  2. 在下面两行添加一个 Grid 结束标签 </Grid>*

* 我们添加了一个空行,以便在我们粘贴代码时更容易。

它看起来会像下面这样

 

现在,我们将点击 Grid 标签之间的空行,并将下面的代码粘贴进去

<Grid.RowDefinitions>
       <RowDefinition/>
       <RowDefinition Height="44"/>
   </Grid.RowDefinitions>
   <Grid.ColumnDefinitions>
       <ColumnDefinition Width="Auto"/>
       <ColumnDefinition/>
   </Grid.ColumnDefinitions>
   <Rectangle Fill="Red" Width="44"/>
   <Rectangle Fill="Blue" Grid.Row="1"/>
   <Rectangle Fill="Green" Grid.Column="1"/>
   <Rectangle Fill="Orange" Grid.Row="1" Grid.Column="1"/>


它看起来会像

 

代码来源: https://docs.microsoft.com/en-us/windows/uwp/design/layout/layout-panels

#############################################################################

侧边栏:可能的 Visual Studio 设计视图错误

我注意到,如果我的设计视图太小,那么不知何故,设计视图将呈现为主页面背景透明的样子。上一张图片中的任何矩形形状都不会显示出来。

如果您没有看到上一张图片中显示的颜色,请尝试调整设计视图的大小,直到您看到它们。

#############################################################################

Grid:行和列

我认为这段代码很有帮助,因为它能让我们轻松地看到我们的网格现在被分成了两行两列。

现在,我们应该能够调整这些值以达到我们想要的效果。我们实际上想要左边有两列,右边只有一列。

基本上,我们希望右边的列跨越左边的两列,而且我们实际上不需要橙色列,所以让我们删除它,看看会发生什么。

 

为此,转到那一行,高亮显示它,然后按 [Delete] 键。

当您这样做时,它看起来会像下面这样

 

 

底行变白

请注意,底部的列现在是默认颜色(白色——即 ApplicationBackgroundThemeBrush)。然而,该列仍然存在。我们希望右边的列跨越整个页面高度。换句话说,该列应该跨越所有行。为了实现这一点,我们需要在该列中添加一个属性,该属性恰好命名为 Grid.RowSpan。

Grid.RowSpan

当我们添加这个新属性时,我们只需提供一个整数,指示它应该跨越多少行。在我们的例子中,值为二。以下是添加到当前填充绿色颜色的 Rectangle 中的代码。

Grid.RowSpan="2"

 

当您添加这段代码时,它看起来会像下面这样

 

 

DesignView 自动更新

当您进行更改时,DesignView 会自动更新,底部列也变成绿色,因为我们右边的列现在跨越了两行。

 

RowDefinitions 解释

让我们关注 RowDefinitions 以及它们的含义。当前的 XAML 用于 RowDefinitions 如下所示

<Grid.RowDefinitions>

           <RowDefinition/>

           <RowDefinition Height="44"/>

    </Grid.RowDefinitions>

 

这定义了两行。

 

第一行的高度或宽度是未确定的,因为它没有属性。这意味着它将由其他行的影响来定义。

第二行的高度只有 44 像素。我们可以看到底部蓝绿相间的行非常窄,因为它只有 44 像素。

更改 Height 属性

让我们继续并将该值更改为 250,这样该行就会稍微大一些。

当您进行更改时,它看起来会像下面这样

 

运行应用程序 - CTRL-F5

进行此更改后,继续运行应用程序。您可以按 CTRL-F5,这将生成应用程序并在关闭调试的情况下运行它。

 

应用程序运行时调整窗口大小

如果您调整窗口大小,您将看到右侧尺寸将始终占据两行。您还将看到左上角块(红色)是成比例的,而蓝色区域的高度始终为 250 像素。

 

但是,我们需要的是红色部分刚好足以容纳我们的 CalendarView,而蓝色区域刚好足以容纳我们的 ListView。让我们看看是否能做一些修改来使其看起来像那样。关闭应用程序,回到 Visual Studio,我们将做一些修改。

 

拖放控件

我基本上使用了带有颜色的示例代码,以便在本教程中更容易地定位行和列。

现在,我们想将一个 CalendarView 拖放到我们的页面*上。

* 从现在开始,我将把我们的应用程序窗口称为页面,因为 XAML 元素就是这样命名的。

添加 CalendarView

从工具箱的 [所有 XAML 控件] 中抓取一个 CalendarView ,将其拖到页面上,然后将其放在红色框中。

 

检查 XAML

您可以看到它将 CalendarView 元素添加到 XAML 中 Grid 元素的末尾。

 

此外,请注意 CalendarView 认为我们是以绝对坐标将其拖放的,并且该元素包含 HorizontalAlignment 和 Margin 标签,这些标签将其放置在页面的其他项的相对位置。在这种情况下,我们不希望控件这样定位。

这使得一切看起来有点混乱。我们需要在 CalendarView 上设置一些 XAML 属性,使其真正成为 Grid 的列和行之一。

 

首先,删除 Margin 属性及其值。


设置 GridColumn / GridRow

现在,让我们告诉布局 CalendarView 实际上是网格的一部分,并且是 GridColumn 零和行零。

渲染顺序

我将更改 XAML 中的两项内容,然后向您展示图片。但首先,仔细看看上一张图片中的红色矩形。它实际上并不仅仅是您看到的那么小一块。它实际上延伸到了 CalendarView 的后面。

目前,矩形位于 CalendarView 后面,因为对象在屏幕上的渲染顺序。如果没有额外的 XAML 来更改 Z-Order ,元素(对象)将按照它们在 XAML 中出现的顺序绘制。这意味着红色矩形先绘制,然后是蓝色,然后是绿色。最后,CalendarView 绘制在红色矩形之上。当我说将 XAML 改为将 CalendarView 移到上面时,您将看到红色矩形将以更高的 Z-Order 号绘制,它将位于 CalendarView 之上。

 

将您的 CalendarView XAML 更改为如下所示

<CalendarView HorizontalAlignment="Left" Grid.Row="0" Grid.Column="0" VerticalAlignment="Top"/>

进行此更改后,将其移动到 <Grid.ColumnDefinitions> 之后的第一个项目

 

当您进行此更改并移动该行时,一切都会像这样

 

出现空格(行)

另外请注意,它现在认为有第三行的空间(空白)。我们需要解决这个问题。

我认为开始解决这个问题的方法是将我们的 ListView 控件拖放到蓝色区域。

添加 ListView

我刚刚拖放了一个新的 ListView,它实际上并没有显示在 DesignView 中。不过它在 XAML 中,位于 Grid 的底部。

 

编辑 ListView XAML

我们将采取相同的步骤来尝试修复此控件。

  1. 删除 Margin 属性及其值。

  2. 将其移到 XAML 中,使其成为 CalendarView 之后的下一个控件

  3. 添加适当的 Grid.Row 和 Grid.Column 值。

 

我还会删除蓝色 Rectangle 元素。

 

这是 Grid XAML 的当前状态。

 <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" >

       <Grid.RowDefinitions >

           <RowDefinition Height="Auto" />

           <RowDefinition Height="250"/>

       </Grid.RowDefinitions>

       <Grid.ColumnDefinitions>

           <ColumnDefinition Width="Auto"/>

           <ColumnDefinition/>

       </Grid.ColumnDefinitions>

       <CalendarView HorizontalAlignment="Left" Grid.Row="0" Grid.Column="0" VerticalAlignment="Top"/>

       <ListView HorizontalAlignment="Left" Height="100" Grid.Row="1" Grid.Column="0" VerticalAlignment="Top" Width="100"/>

       <Rectangle Fill="Red" Width="44"/>

       <Rectangle Fill="Green" Grid.RowSpan="2" Grid.Column="1"/>

    </Grid>

XAML 设计中的更多挑战

但我们仍然有那个奇怪的最后一行,它在做奇怪的事情。另外,ListView 的背景色是白色的,所以您很难分辨它的位置。

我将采取的修复措施

  • 我正在删除红色 Rectangle 元素,因为现在我们不需要它来进行对齐。
  • 我还会将 RichEditBox 拖放到绿色矩形区域,并尝试将其正确调整。

 

VerticalAlignment 和 HorizontalAlignment Stretch

我不得不进行一些搜索,以发现如何让 ListView 占据其外部容器(Grid.Row 和 Grid.Column)中的所有可用空间。为此,我必须更改 VerticalAlignment HorizontalAlignment 并将其设置为“Stretch”值。

我对 RichEditBox 做了同样的处理。这是修改后的 XAML,以便您可以跟上。

修改后的 XAML 遵循教程

 <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" >

       <Grid.RowDefinitions >

           <RowDefinition Height="Auto" />

           <RowDefinition Height="400"/>

       </Grid.RowDefinitions>

       <Grid.ColumnDefinitions>

           <ColumnDefinition Width="Auto"/>

           <ColumnDefinition/>

       </Grid.ColumnDefinitions>

       <CalendarView HorizontalAlignment="Left" Grid.Row="0" Grid.Column="0" VerticalAlignment="Top"/>

       <ListView Grid.Row="1" Grid.Column="0"

          HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />

       <RichEditBox Grid.Column="1" Grid.Row="0" Grid.RowSpan="2"

                    HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>

    </Grid>

 

如果您将鼠标悬停在 Visual Studio 中的 DesignView 区域上,它将突出显示控件的边界。您可以看到 RichEditBox 跨越了行并拉伸到了边缘。

 

设计器中难以看到控件

那些未被选中、没有背景色或数据内容的控件在设计器中很难看到,而我们的 ListView 目前就是这种情况。

 

您也可以点击代表某个项目的 XAML,该项目将在 Visual Studio 的 DesignView 中被激活。

以编程方式添加模拟数据以供查看

现在,让我们以编程方式向 ListView 和 RichEditBox 添加一些模拟数据,然后运行应用程序看看会得到什么。

页面加载完成后,我们将添加模拟数据。为此,请点击 XAML 中的 <Page> 元素(这是访问它的最简单方法,因为 DesignView 有控件和容器的多层嵌套)。

 

单击 <Page> 元素后,转到属性窗口,然后单击[闪电]图标。该图标允许您访问可以为其编写处理程序的系统事件。在我们的例子中,我们正在寻找 Loaded 事件,所以向下滚动直到看到该事件。

 

双击 TextBox 添加事件

当您找到 Loaded 事件时,只需双击 Loaded 事件旁边的 TextBox 。如果您正确双击,您将知道,因为屏幕会闪烁,Visual Studio 会将您移至 MainPage.xaml.cs ,在那里它已自动添加了一个名为 Page_Loaded() 的新方法。

您的光标将闪烁在 { } 括号内,这是 Visual Studio 表示它已准备好您输入代码的方式。

添加事件会更改 XAML

当然,就像我们在第 2 章中学到的关于 Button 一样,添加一个事件会在关联的 XAML 元素中添加一个属性。如果您看一下 XAML 中的 <Page> 元素,您会看到以下内容

 

注意:我还没有命名 XAML Page 元素,所以 Visual Studio 会自行引用 Page 对象为 Page。如果我们命名了它,那会更好一些,因为它会将此方法命名为 <NAME>_Loaded ,其中 <NAME> 等于 Name 属性的值。这样会更清楚。

我已为 RichEditBox 和 ListView 分别命名,以便更容易使用它们,方法是向它们添加 Name=”” 属性。这是 MainPage.xaml 文件的更新 XAML。如果您正在跟随,请替换您的整个文件,您将拥有一个可以继续使用的良好 XAML 文件。

<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="400"/>

       </Grid.RowDefinitions>

       <Grid.ColumnDefinitions>

           <ColumnDefinition Width="Auto"/>

           <ColumnDefinition/>

       </Grid.ColumnDefinitions>

       <CalendarView HorizontalAlignment="Left" Grid.Row="0" Grid.Column="0" VerticalAlignment="Top"/>

       <ListView Name="EntriesListView" Grid.Row="1" Grid.Column="0"

           HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />

       <RichEditBox Name="MainRichEdit" Grid.Column="1" Grid.Row="0" Grid.RowSpan="2"

                    HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>

   </Grid>

</Page>

 

完成之后,您可以将以下代码添加到 Page_Loaded() 方法(在 MainPage.xaml.cs 中),以便 EntriesListView 现在包含一些数据。这将与上面的 XAML 一起工作,因为我将 ListView 命名为 EntriesListView。

          EntriesListView.Items.Add("super");

          EntriesListView.Items.Add("extra");

           EntriesListView.Items.Add("maximum");

           EntriesListView.Items.Add("advanced");

           EntriesListView.Items.Add("efficient");

 

构建和运行

生成并运行应用程序 (CTRL-F5),以便我们可以开始了解它的外观。

我的看起来像

值出现在 ListView 中

现在这些值出现在 ListView 中了。对我来说,CalendarView 占用的空间有多大,ListView 中每个项目的大小有多大,这有点令人震惊。

但是请注意,您已经可以使用 RichEditBox 进行输入了。当然,没有什么被保存,它几乎没有其他功能,但如果您按 Ctrl-Shift-L ,它将允许您在编号/项目符号选项之间循环以更改文本。

结论

一天的工作已经很不错了。您已经学会了很多关于使用 Grid 进行布局的知识,而且它确实不那么痛苦,而且看起来与我最初的 WinForm 应用程序非常相似。

 

我在这里暂停一下,让您喘口气(我也一样),思考一下您学到的东西。

下次我们将开始为应用程序添加更多功能,并希望能将其保存为条目,然后这些条目将显示在我们的 ListView 中。

 

历史

2017-11-27 - 首次发布

 

© . All rights reserved.