UI 和导航
作者: Erik Reitan
下载 Wingtip Toys 示例项目 (C#) 或下载电子书 (PDF)
本教程系列将介绍如何使用 ASP.NET 4.5 和 Microsoft Visual Studio Express 2013 for Web 生成 ASP.NET Web 窗体应用程序。 Visual Studio 2013 包含 C# 源代码 的项目随本教程系列一起提供。
在本教程中,你将修改默认 Web 应用程序的 UI 以支持 Wingtip Toys Store Front 应用程序的功能。 此外,还将添加简单和数据绑定导航。 本教程基于上一教程“创建数据访问层”,是 Wingtip Toys 系列教程的一部分。
学习内容:
- 如何更改 UI 以支持 Wingtip Toys 商店前端应用程序的功能。
- 如何配置 HTML5 元素以包含页面导航。
- 如何创建数据驱动控件以导航到特定产品数据。
- 如何显示使用 Entity Framework Code First 创建的数据库中的数据。
ASP.NET Web 窗体允许你为 Web 应用程序创建动态内容。 每个 ASP.NET 网页都以类似于静态 HTML 网页(不包含基于服务器的处理的页面)的方式创建,但 ASP.NET 网页包含额外的元素,ASP.NET 识别和处理页面运行时生成 HTML。
使用静态 HTML 页面(.htm 或 .html 文件),服务器通过读取文件并将其按原样发送到浏览器来完成 Web
请求。 相比之下,当有人请求 ASP.NET 网页(.aspx 文件)时,页面在 Web 服务器上作为程序运行。 在页面运行时,它可以执行网站所需的任何任务,包括计算值、读取或写入数据库信息或调用其他程序。 作为其输出,页面动态生成标记(如 HTML 中的元素),并将此动态输出发送到浏览器。
修改 UI
通过修改 Default.aspx 页面,可以继续学习本教程系列。 将修改已由用于创建应用程序的默认模板建立的 UI。 创建任何 Web 窗体应用程序时,通常会进行修改。 你将通过更改标题、替换某些内容以及删除不需要的默认内容来执行此操作。
打开或切换到 Default.aspx 页。
如果页面显示在 “设计 ”视图中,请切换到 “源 ”视图。
在指令中的页面
@Page
顶部,将Title
属性更改为“欢迎”,如下面的黄色突出显示。<%@ Page Title="Welcome" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WingtipToys._Default" %>
此外,在 Default.aspx 页上,替换标记中包含的
<asp:Content>
所有默认内容,以便标记如下所示。<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server"> <h1><%: Title %>.</h1> <h2>Wingtip Toys can help you find the perfect gift.</h2> <p class="lead">We're all about transportation toys. You can order any of our toys today. Each toy listing has detailed information to help you choose the right toy.</p> </asp:Content>
通过从“文件”菜单中选择“保存Default.aspx”保存Default.aspx页。
生成的 Default.aspx 页面如下所示:
<%@ Page Title="Welcome" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WingtipToys._Default" %>
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<h1><%: Title %>.</h1>
<h2>Wingtip Toys can help you find the perfect gift.</h2>
<p class="lead">We're all about transportation toys. You can order
any of our toys today. Each toy listing has detailed
information to help you choose the right toy.</p>
</asp:Content>
在此示例中,你已设置 Title
指令的属性 @Page
。 当 HTML 显示在浏览器中时,服务器代码 <%: Page.Title %>
将解析为属性中包含的 Title
内容。
示例页包含构成 ASP.NET 网页的基本元素。 该页包含 HTML 页面中可能具有的静态文本,以及特定于 ASP.NET 的元素。 Default.aspx页中包含的内容将与母版页内容集成,本教程稍后将对此进行说明。
@Page 命令
ASP.NET Web 窗体通常包含允许你为页面指定页面属性和配置信息的指令。 指令由 ASP.NET 用作如何处理页面的说明,但它们不会呈现为发送到浏览器的标记的一部分。
最常用的指令是 @Page
指令,它允许你为页面指定许多配置选项,包括:
- 页面中代码的服务器编程语言,例如 C# 。
- 页面是页面中直接包含服务器代码的页面(称为单文件页),还是它是一个在单独的类文件中具有代码的页面,这称为代码隐藏页。
- 页面是否具有关联的母版页,因此应被视为内容页。
- 调试和跟踪选项。
如果未在页面中包括 @Page
指令,或者该指令不包含特定设置,则会从 Web.config 配置文件或 Machine.config 配置文件继承设置。 Machine.config 文件为计算机上运行的所有应用程序提供其他配置设置。
注意
Machine.config 还提供所有可能的配置设置的详细信息。
Web 服务器控件
在大多数 ASP.NET Web 窗体应用程序中,将添加允许用户与页面交互的控件,例如按钮、文本框、列表等。 这些 Web 服务器控件类似于 HTML 按钮和输入元素。 但是,它们是在服务器上处理的,允许你使用服务器代码设置其属性。 这些控件还会引发可在服务器代码中处理的事件。
服务器控件使用特殊语法,ASP.NET 页面运行时识别。 ASP.NET 服务器控件的标记名称以 asp:
前缀开头。 这允许 ASP.NET 识别和处理这些服务器控件。 如果控件不是 .NET Framework 的一部分,则前缀可能有所不同。 除了 asp:
前缀,ASP.NET 服务器控件还包括 runat="server"
属性和 ID
可用于在服务器代码中引用控件的属性。
当页面运行时,ASP.NET 标识服务器控件并运行与这些控件关联的代码。 在浏览器中显示某些 HTML 或其他标记时,许多控件都会将某些 HTML 或其他标记呈现到页面中。
服务器代码
大多数 ASP.NET Web 窗体应用程序都包含在处理页面时在服务器上运行的代码。 如上所述,服务器代码可用于执行各种操作,例如将数据添加到 ListView 控件。 ASP.NET 支持在服务器上运行的多种语言,包括 C#、Visual Basic、J# 和其他语言。
ASP.NET 支持两个模型来编写网页的服务器代码。 在单文件模型中,页面的代码位于包含属性的 runat="server"
脚本元素中。 或者,可以在单独的类文件中为页面创建代码,该文件称为代码隐藏模型。 在这种情况下,ASP.NET Web 窗体页通常不包含服务器代码。 相反,该@Page
指令包含将.aspx页与其关联的代码隐藏文件链接的信息。
CodeBehind
指令中包含的@Page
属性指定单独的类文件的名称,属性Inherits
指定与页面对应的代码隐藏文件中类的名称。
更新母版页
在 ASP.NET Web 窗体中,母版页允许你为应用程序中的页面创建一致的布局。 单个母版页定义应用程序中所有页面(或一组页面)所需的外观和标准行为。 然后,可以创建包含要显示的内容的各个内容页面,如上所述。 当用户请求内容页时,ASP.NET 将它们与母版页合并,以生成将母版页布局与内容页中的内容相结合的输出。
新网站需要一个徽标才能在每个页面上显示。 若要添加此徽标,可以修改母版页上的 HTML。
在解决方案资源管理器中,找到并打开 Site.Master 页。
如果页面位于 “设计 ”视图中,请切换到 “源 ”视图。
通过 修改或添加 突出显示为黄色的标记来更新母版页:
<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="WingtipToys.SiteMaster" %> <!DOCTYPE html> <html lang="en"> <head runat="server"> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title><%: Page.Title %> - Wingtip Toys</title> <asp:PlaceHolder runat="server"> <%: Scripts.Render("~/bundles/modernizr") %> </asp:PlaceHolder> <webopt:bundlereference runat="server" path="~/Content/css" /> <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" /> </head> <body> <form runat="server"> <asp:ScriptManager runat="server"> <Scripts> <%--To learn more about bundling scripts in ScriptManager see https://go.microsoft.com/fwlink/?LinkID=301884 --%> <%--Framework Scripts--%> <asp:ScriptReference Name="MsAjaxBundle" /> <asp:ScriptReference Name="jquery" /> <asp:ScriptReference Name="bootstrap" /> <asp:ScriptReference Name="respond" /> <asp:ScriptReference Name="WebForms.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebForms.js" /> <asp:ScriptReference Name="WebUIValidation.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebUIValidation.js" /> <asp:ScriptReference Name="MenuStandards.js" Assembly="System.Web" Path="~/Scripts/WebForms/MenuStandards.js" /> <asp:ScriptReference Name="GridView.js" Assembly="System.Web" Path="~/Scripts/WebForms/GridView.js" /> <asp:ScriptReference Name="DetailsView.js" Assembly="System.Web" Path="~/Scripts/WebForms/DetailsView.js" /> <asp:ScriptReference Name="TreeView.js" Assembly="System.Web" Path="~/Scripts/WebForms/TreeView.js" /> <asp:ScriptReference Name="WebParts.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebParts.js" /> <asp:ScriptReference Name="Focus.js" Assembly="System.Web" Path="~/Scripts/WebForms/Focus.js" /> <asp:ScriptReference Name="WebFormsBundle" /> <%--Site Scripts--%> </Scripts> </asp:ScriptManager> <div class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" runat="server" href="~/">Wingtip Toys</a> </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a runat="server" href="~/">Home</a></li> <li><a runat="server" href="~/About">About</a></li> <li><a runat="server" href="~/Contact">Contact</a></li> </ul> <asp:LoginView runat="server" ViewStateMode="Disabled"> <AnonymousTemplate> <ul class="nav navbar-nav navbar-right"> <li><a runat="server" href="~/Account/Register">Register</a></li> <li><a runat="server" href="~/Account/Login">Log in</a></li> </ul> </AnonymousTemplate> <LoggedInTemplate> <ul class="nav navbar-nav navbar-right"> <li><a runat="server" href="~/Account/Manage" title="Manage your account">Hello, <%: Context.User.Identity.GetUserName() %> !</a></li> <li> <asp:LoginStatus runat="server" LogoutAction="Redirect" LogoutText="Log off" LogoutPageUrl="~/" OnLoggingOut="Unnamed_LoggingOut" /> </li> </ul> </LoggedInTemplate> </asp:LoginView> </div> </div> </div> <div id="TitleContent" style="text-align: center"> <a runat="server" href="~/"> <asp:Image ID="Image1" runat="server" ImageUrl="~/Images/logo.jpg" BorderStyle="None" /> </a> <br /> </div> <div class="container body-content"> <asp:ContentPlaceHolder ID="MainContent" runat="server"> </asp:ContentPlaceHolder> <hr /> <footer> <p>© <%: DateTime.Now.Year %> - Wingtip Toys</p> </footer> </div> </form> </body> </html>
此 HTML 将显示 Web 应用程序的 Images 文件夹中名为logo.jpg的图像,稍后将添加该图像。 当使用母版页的页面显示在浏览器中时,将显示徽标。 如果用户单击徽标,用户将导航回 Default.aspx 页面。 HTML 定位标记 <a>
包装图像服务器控件,并允许将图像包含在链接中。 href
定位标记的属性将网站的根“”~/
指定为链接位置。 默认情况下,当用户导航到网站的根目录时, 将显示Default.aspx 页面。 图像<asp:Image>
服务器控件包括添加的属性,例如BorderStyle
,在浏览器中显示时呈现为 HTML 的属性。
母版页
母版页是扩展名为 .master(例如 Site.Master)的 ASP.NET 文件,其预定义布局可以包括静态文本、HTML 元素和服务器控件。 母版页由一个特殊 @Master
指令标识,该指令替换 @Page
用于普通 .aspx页的 指令。
除了 @Master
指令,母版页还包含页面的所有顶级 HTML 元素,例如 html
, head
和 form
。 例如,在上面添加的母版页上,使用布局的 HTML table
、 img
公司徽标、静态文本和服务器控件的元素来处理网站的常见成员身份。 可以将任何 HTML 和任何 ASP.NET 元素用作母版页的一部分。
除了所有页面上显示的静态文本和控件外,母版页还包括一个或多个 ContentPlaceHolder 控件。 这些占位符控件定义将显示可替换内容的区域。 反过来,可以使用内容服务器控件在内容页中定义可替换的内容,例如Default.aspx。
添加图像文件
上面引用的徽标图像以及所有产品图像都必须添加到 Web 应用程序中,以便可以在浏览器中显示项目时看到它们。
从 MSDN 示例网站下载:
ASP.NET 4.5 Web 窗体和 Visual Studio 2013 入门 - Wingtip Toys (C#)
下载内容包括 WingtipToys-Assets 文件夹中用于创建示例应用程序的资源。
如果尚未这样做,请使用上述链接从 MSDN 示例网站下载压缩的示例文件。
下载后,打开.zip文件并将内容复制到计算机上的本地文件夹。
查找并打开 WingtipToys-Assets 文件夹。
通过拖放,将目录文件夹从本地文件夹复制到 Visual Studio 解决方案资源管理器中的 Web 应用程序项目的根目录。
接下来,通过在解决方案资源管理器中右键单击 WingtipToys 项目并选择“添加新>文件夹”,创建名为 Images 的新文件夹。
将文件资源管理器的 WingtipToys-Assets 文件夹中logo.jpg文件复制到 Visual Studio 解决方案资源管理器 Web 应用程序项目的 Images 文件夹。
单击解决方案资源管理器顶部的“显示所有文件”选项,更新文件列表(如果看不到新文件)。
解决方案资源管理器现在显示更新的项目文件。
添加页面
在向 Web 应用程序添加导航之前,首先添加两个新页面,你将导航到该页面。 本教程系列的后面部分将在这些新页面上显示产品和产品详细信息。
在解决方案资源管理器中,右键单击 WingtipToys,单击“添加”,然后单击“新建项”。
随即出现“添加新项”对话框。选择左侧的 Visual C# ->Web 模板组。 然后, 从中间列表中选择具有母版页 的 Web 窗体,并将其 命名为ProductList.aspx。
选择 Site.Master 以将母版页附加到新创建的 .aspx 页。
按照这些步骤添加名为 ProductDetails.aspx 的其他页面。
更新 Bootstrap
Visual Studio 2013 项目模板使用 Bootstrap,这是 Twitter 创建的布局和主题框架。 Bootstrap 使用 CSS3 提供响应式设计,这意味着布局可以动态适应不同的浏览器窗口大小。 还可以使用 Bootstrap 主题功能轻松影响应用程序外观的变化。 默认情况下,Visual Studio 2013 中的 ASP.NET Web 应用程序模板包括 Bootstrap 作为 NuGet 包。
在本教程中,你将通过替换 Bootstrap CSS 文件来更改 Wingtip Toys 应用程序的外观。
在解决方案资源管理器中,打开“内容”文件夹。
右键单击 bootstrap.css 文件并将其重命名为 bootstrap-original.css。
将 bootstrap.min.css 重命名为 bootstrap-original.min.css。
在解决方案资源管理器中,右键单击“内容”文件夹,然后在文件资源管理器中选择“打开文件夹”。
将显示文件资源管理器。 将下载的启动 CSS 文件保存到此位置。在浏览器中转到 https://bootswatch.com/3/。
滚动浏览器窗口,直到看到 Cerulean 主题。
将 bootstrap.css 文件和 bootstrap.min.css 文件下载到 内容 文件夹。 使用之前打开文件资源管理器窗口中显示的内容文件夹的路径。
在解决方案资源管理器顶部的 Visual Studio 中,选择“显示所有文件”选项以显示内容文件夹中的新文件。
你将在内容文件夹中看到两个新的 CSS 文件,但请注意,每个文件名旁边的图标灰显。这意味着文件尚未添加到项目中。
右键单击bootstrap.css和bootstrap.min.css文件,然后选择“包括在项目中”。
在本教程的后面部分运行 Wingtip Toys 应用程序时,将显示新的 UI。
注意
ASP.NET Web 应用程序模板使用 项目根目录中的 Bundle.config 文件来存储 Bootstrap CSS 文件的路径。
修改默认导航
通过更改 Site.Master 页中的无序导航列表元素,可以修改应用程序中每个页面的默认导航。
在解决方案资源管理器中,找到并打开 Site.Master 页。
将黄色突出显示的其他导航链接添加到如下所示的无序列表:
<ul class="nav navbar-nav"> <li><a runat="server" href="~/">Home</a></li> <li><a runat="server" href="~/About">About</a></li> <li><a runat="server" href="~/Contact">Contact</a></li> <li><a runat="server" href="~/ProductList">Products</a></li> </ul>
如上面的 HTML 所示,你修改了包含带有链接href
属性的定位标记<a>
的每个行项<li>
。 每个 href
指向 Web 应用程序中的页面。 在浏览器中,当用户单击其中一个链接(如产品)时,他们将导航到包含在(如ProductList.aspx)中的href
页面。 将在本教程结束时运行应用程序。
注意
波形符 (~
) 字符用于指定 href
路径从项目的根目录开始。
添加数据控件以显示导航数据
接下来,添加一个控件以显示数据库中的所有类别。 每个类别将充当指向ProductList.aspx页面的链接。 当用户在浏览器中单击某个类别链接时,他们将导航到产品页面,只看到与所选类别关联的产品。
你将使用 ListView 控件显示数据库中包含的所有类别。 若要向 母版页添加 ListView 控件,请执行以下操作:
在 Site.Master 页中,在包含前面添加的
id="TitleContent"
元素后面<div>
添加以下突出显示<div>
的元素:<div id="TitleContent" style="text-align: center"> <a runat="server" href="~/"> <asp:Image ID="Image1" runat="server" ImageUrl="~/img/logo.jpg" BorderStyle="None" /> </a> <br /> </div> <div id="CategoryMenu" style="text-align: center"> <asp:ListView ID="categoryList" ItemType="WingtipToys.Models.Category" runat="server" SelectMethod="GetCategories" > <ItemTemplate> <b style="font-size: large; font-style: normal"> <a href="/ProductList.aspx?id=<%#: Item.CategoryID %>"> <%#: Item.CategoryName %> </a> </b> </ItemTemplate> <ItemSeparatorTemplate> | </ItemSeparatorTemplate> </asp:ListView> </div>
此代码将显示数据库中的所有类别。 ListView 控件将每个类别名称显示为链接文本,并包含指向ProductList.aspx页的链接,其中包含包含ID
类别的查询字符串值。 通过在 ListView 控件中设置ItemType
属性,数据绑定表达式Item
在节点中ItemTemplate
可用,并且该控件将变为强类型。 可以使用 IntelliSense 选择对象的详细信息 Item
,例如指定 CategoryName
。 此代码包含在标记数据绑定表达式的容器 <%#: %>
中。 通过将 (:) 添加到前缀的 <%#
末尾,数据绑定表达式的结果是 HTML 编码的。 当结果进行 HTML 编码时,应用程序会更好地防范跨站点脚本注入(XSS)和 HTML 注入攻击。
注意
提示
通过键入开发期间添加代码时,可以确定找到对象的有效成员,因为强类型化的数据控件显示基于 IntelliSense 的可用成员。 当你键入代码(如属性、方法和对象)时,IntelliSense 提供上下文适当的代码选择。
在下一步中,你将实现 GetCategories
检索数据的方法。
将数据控件链接到数据库
在数据控件中显示数据之前,需要将数据控件链接到数据库。 若要创建链接,可以修改Site.Master.cs文件背后的代码。
在解决方案资源管理器中,右键单击 Site.Master 页,然后单击“查看代码”。 Site.Master.cs文件在编辑器中打开。
在Site.Master.cs文件的开头附近,添加另外两个命名空间,以便所有包含的命名空间如下所示:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Linq; using WingtipToys.Models;
在事件处理程序后面
Page_Load
添加突出显示GetCategories
的方法,如下所示:protected void Page_Load(object sender, EventArgs e) { } public IQueryable<Category> GetCategories() { var _db = new WingtipToys.Models.ProductContext(); IQueryable<Category> query = _db.Categories; return query; }
当浏览器中加载使用母版页的任何页面时,将执行上述代码。 ListView
在本教程前面添加的控件(名为“categoryList”)使用模型绑定来选择数据。 在控件的 ListView
标记中,将控件 SelectMethod
的属性设置为 GetCategories
方法,如上所示。 控件 ListView
在页面生命周期中的适当时间调用 GetCategories
该方法,并自动绑定返回的数据。 在下一教程中,你将了解有关绑定数据的详细信息。
运行应用程序和创建数据库
在本教程系列前面,你创建了一个名为“ProductDatabaseInitializer”的初始值设定项类,并在global.asax.cs文件中指定了此类。 实体框架将在应用程序首次运行时生成数据库,因为Application_Start
global.asax.cs文件中包含的方法将调用初始值设定项类。 初始值设定项类将使用前面在本教程系列中添加的模型类(Category
和 Product
)来创建数据库。
- 在解决方案资源管理器中,右键单击Default.aspx页,然后选择“设为起始页”。
- 在 Visual Studio 中,按 F5。
在第一次运行期间设置所有内容需要一点时间。
运行应用程序时,将编译应用程序,并在App_Data文件夹中创建名为wingtiptoys.mdf的数据库。 在浏览器中,你将看到类别导航菜单。 此菜单是通过从数据库检索类别生成的。 在下一教程中,你将实现导航。 - 关闭浏览器以停止正在运行的应用程序。
查看数据库
打开 Web.config 文件并查看连接字符串部分。 可以看到AttachDbFilename
连接字符串中的值指向 DataDirectory
Web 应用程序项目的值。 该值|DataDirectory|
是表示项目中App_Data文件夹的保留值。 此文件夹是从实体类创建的数据库所在的位置。
<connectionStrings>
<add name="DefaultConnection"
connectionString="Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=aspnet-WingtipToys-20120302100502;Integrated Security=True"
providerName="System.Data.SqlClient" />
<add name="WingtipToys"
connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\wingtiptoys.mdf;Integrated Security=True"
providerName="System.Data.SqlClient " />
</connectionStrings>
注意
如果App_Data文件夹不可见或文件夹为空,请选择“刷新”图标,然后选择解决方案资源管理器窗口顶部的“显示所有文件”图标。 可能需要扩展解决方案资源管理器窗口的宽度才能显示所有可用的图标。
现在,可以使用“服务器资源管理器”窗口检查wingtiptoys.mdf数据库文件中包含的数据。
展开 App_Data 文件夹。 如果App_Data文件夹不可见,请参阅上面的说明。
如果wingtiptoys.mdf数据库文件不可见,请选择“刷新”图标,然后选择解决方案资源管理器窗口顶部的“显示所有文件”图标。
右键单击 wingtiptoys.mdf 数据库文件,然后选择“ 打开”。
显示服务器资源管理器 。展开 “表” 文件夹。
右键单击“产品”表,然后选择“显示表数据”。
将显示“产品”表。此视图允许你手动查看和修改 Products 表中的数据。
关闭“产品”表窗口。
在 服务器资源管理器中,再次右键单击 “产品 ”表,然后选择“ 打开表定义”。
将显示 Products 表的数据设计。在 T-SQL 选项卡中,会看到用于创建表的 SQL DDL 语句。 还可以使用“ 设计 ”选项卡中的 UI 修改架构。
在服务器资源管理器中,右键单击 WingtipToys 数据库并选择“关闭连接”。
通过从 Visual Studio 分离数据库,数据库架构将能够稍后在本教程系列中修改。返回到 解决方案资源管理器by 选择服务器资源管理器窗口底部的“解决方案资源管理器”选项卡。
总结
在系列教程中,你添加了一些基本的 UI、图形、页面和导航。 此外,还运行了 Web 应用程序,该应用程序从上一教程中添加的数据类创建了数据库。 你还通过直接查看数据库来查看数据库的 Products 表的内容。 在下一教程中,你将显示数据库中的数据项和详细信息。