第 2 章的摘要。Summary of Chapter 2. 应用剖析Anatomy of an app

下载示例下载示例Download Sample Download the sample


此页上的说明表明其中 Xamarin.Forms 已脱离一书中介绍的内容的区域。Notes on this page indicate areas where Xamarin.Forms has diverged from the material presented in the book.

在 Xamarin.Forms 应用程序中,占用屏幕空间的对象称为可视元素、 通过封装 VisualElement 类。In a Xamarin.Forms application, objects that occupy space on the screen are known as visual elements, encapsulated by the VisualElement class. 可视元素可以拆分为三个类别对应于这些类:Visual Elements can be split into three categories corresponding to these classes:

一个Page派生占据整个屏幕或几乎整个屏幕。A Page derivative occupies the entire screen, or nearly the entire screen. 通常情况下,一个页面的子级是Layout派生类来组织子可视元素。Often, the child of a page is a Layout derivative to organize child visual elements. 子级Layout可以是其他Layout类或View派生类 (通常称为元素),这是熟悉的对象,如文本、 位图、 滑块、 按钮、 列表框等。The children of the Layout can be other Layout classes or View derivatives (often called elements), which are familiar objects such as text, bitmaps, sliders, buttons, list boxes, and so on.

本章演示如何通过在创建应用程序 Label ,这是View显示文本的派生类。This chapter demonstrates how to create an application by focusing on the Label, which is the View derivative that displays text.

假设你好Say hello

使用安装 Xamarin 平台,你可以创建新的 Xamarin.Forms 解决方案在 Visual Studio 或 Visual Studio for mac。With the Xamarin platform installed, you can create a new Xamarin.Forms solution in Visual Studio or Visual Studio for Mac. Hello 解决方案使用可移植类库的通用代码。The Hello solution uses a Portable Class Library for the common code.


.NET Standard 库已替换为可移植类库。Portable Class Libraries have been replaced by .NET Standard libraries. 本书中的所有示例代码已都转换为使用.NET 标准库。All the sample code from the book has been converted to use .NET standard libraries.

此示例演示在 Visual Studio 中创建不作任何修改的 Xamarin.Forms 解决方案。This sample demonstrates a Xamarin.Forms solution created in Visual Studio with no modifications. 此解决方案由六个项目组成:The solution consists of six projects:

  • Hello,由其他项目共享的可移植类库 (PCL)Hello, a Portable Class Library (PCL) shared by the other projects
  • Hello.Droid,适用于 Android 的应用程序项目Hello.Droid, an application project for Android
  • Hello.iOS,适用于 iOS 的应用程序项目Hello.iOS, an application project for iOS
  • Hello.UWP,通用 Windows 平台 (Windows 10 和 Windows 10 移动版) 的应用程序项目Hello.UWP, an application project for the Universal Windows Platform (Windows 10 and Windows 10 Mobile)
  • Hello.Windows,用于 Windows 8.1 的应用程序项目Hello.Windows, an application project for Windows 8.1
  • Hello.WinPhone,适用于 Windows Phone 8.1 应用程序项目Hello.WinPhone, an application project for Windows Phone 8.1


Xamarin.Forms 不再支持 Windows 8.1、 Windows Phone 8.1 或 Windows 10 移动版,但在 Windows 10 桌面版上运行的 Xamarin.Forms 应用程序。Xamarin.Forms no longer supports Windows 8.1, Windows Phone 8.1, or Windows 10 Mobile, but Xamarin.Forms applications do run on the Windows 10 desktop.

您可以进行任何这些应用程序项目启动项目,然后生成并在设备或模拟器上运行该程序。You can make any of these application projects the startup project, and then build and run the program on a device or simulator.

在许多 Xamarin.Forms 程序,您不会修改应用程序项目。In many of your Xamarin.Forms programs, you won't be modifying the application projects. 这些通常保持小的存根,只是为了启动该程序。These often remain tiny stubs just to start up the program. 您的大部分将是侧重点的普遍适用于所有应用程序库。Most of your focus will be the library common to all the applications.

文件内Inside the files

显示的视觉对象Hello程序定义的构造函数中 App 类。The visuals displayed by the Hello program are defined in the constructor of the App class. App 派生自 Xamarin.Forms 类 Application App derives from the Xamarin.Forms class Application.


Visual Studio 解决方案模板适用于 Xamarin.Forms 使用 XAML 文件创建一个页面。The Visual Studio solution templates for Xamarin.Forms create a page with a XAML file. 直到本书中未涵盖 XAML第 7 章XAML is not covered in this book until Chapter 7.

引用一部分Hello PCL 项目中包括以下 Xamarin.Forms 程序集:The References section of the Hello PCL project includes the following Xamarin.Forms assemblies:

  • Xamarin.Forms.CoreXamarin.Forms.Core
  • Xamarin.Forms.XamlXamarin.Forms.Xaml
  • Xamarin.Forms.PlatformXamarin.Forms.Platform

引用节的五个应用程序项目包括适用于各个平台的其他程序集:The References sections of the five application projects include additional assemblies that apply to the individual platforms:

  • Xamarin.Forms.Platform.AndroidXamarin.Forms.Platform.Android
  • Xamarin.Forms.Platform.iOSXamarin.Forms.Platform.iOS
  • Xamarin.Forms.Platform.UWPXamarin.Forms.Platform.UWP
  • Xamarin.Forms.Platform.WinRTXamarin.Forms.Platform.WinRT
  • Xamarin.Forms.Platform.WinRT.TabletXamarin.Forms.Platform.WinRT.Tablet
  • Xamarin.Forms.Platform.WinRT.PhoneXamarin.Forms.Platform.WinRT.Phone


引用不再列出程序集,这些项目的部分。The References sections of these projects no longer list the assemblies. 相反,该项目文件包含PackageReference标记引用的 Xamarin.Forms NuGet 包。Instead, the project file contains a PackageReference tags referencing the Xamarin.Forms NuGet package. 引用Visual Studio 列表中的部分Xamarin.Forms包而不是 Xamarin.Forms 程序集。The References section in Visual Studio lists the Xamarin.Forms package rather than the Xamarin.Forms assemblies.

每个应用程序项目包含调用静态Forms.Init中的方法Xamarin.Forms命名空间。Each of the application projects contains a call to the static Forms.Init method in the Xamarin.Forms namespace. 此初始化 Xamarin.Forms 库。This initializes the Xamarin.Forms library. 不同版本的Forms.Init定义为每个平台。A different version of Forms.Init is defined for each platform. 调用此方法可在以下类:The calls to this method can be found in the following classes:

此外,每个平台必须实例化App类共享库中的位置。In addition, each platform must instantiate the App class location in the shared library. 此错误出现在调用LoadApplication为以下几类:This occurs in a call to LoadApplication in the following classes:

否则,这些应用程序项目是正常的"执行任何操作"的程序。Otherwise, these application projects are normal "do nothing" programs.


就可以使用可移植类库 (PCL) 或共享资产项目 (SAP) 中的常见代码创建 Xamarin.Forms 解决方案。It's possible to create a Xamarin.Forms solution with the common code in either a Portable Class Library (PCL) or a Shared Asset Project (SAP). 若要创建的 SAP 解决方案,请在 Visual Studio 中选择共享选项。To create an SAP solution, select the Shared option in Visual Studio. HelloSap 解决方案演示了不作任何修改的 SAP 模板。The HelloSap solution demonstrates the SAP template with no modifications.


.NET Standard 库已替换为可移植类库。Portable Class Libraries has been replaced by .NET Standard libraries. 本书中的所有示例代码已都转换为使用.NET 标准库。All the sample code from the book has been converted to use .NET standard libraries. 否则,PCL 和.NET Standard 库在概念上非常类似。Otherwise, the PCL and .NET Standard libraries are conceptually very similar.

所有通用平台应用程序项目引用的库项目中的都代码库方法捆绑包。The library approach bundles all the common code in a library project referenced by the platform application projects. 使用 SAP 方法时,公共代码有效地在所有平台应用程序项目中存在并在它们之间共享。With the SAP approach, the common code effectively exists in all the platform application projects and is shared among them.

大多数 Xamarin.Forms 开发人员更喜欢库方法。Most Xamarin.Forms developers prefer the library approach. 在本书中,大部分解决方案使用一个库。In this book, most of the solutions use a library. 包括那些使用 SAP Sap项目名称中的后缀。Those that use SAP include an Sap suffix in the project name.

共享项目中的代码可以通过使用为各种平台的不同代码执行与 SAP 方法C#预处理器指令 (#if,#elif,并#endif) 使用这些预定义的标识符:With the SAP approach the code in the shared project can execute different code for the various platforms by using C# preprocessor directives (#if, #elif, and #endif) with these predefined identifiers:

  • iOS: __IOS__iOS: __IOS__
  • Android: __ANDROID__Android: __ANDROID__

在共享库中,可以确定在运行时, 运行哪种平台,您将看到更高版本中这一章。In a shared library, you can determine what platform you're running on at runtime, as you'll see later in this chapter.

标签文本Labels for text

Greetings 解决方案展示了如何添加新C#的文件Greetings项目。The Greetings solution demonstrates how to add a new C# file to the Greetings project. 此文件定义一个名为GreetingsPage派生ContentPageThis file defines a class named GreetingsPage that derives from ContentPage. 在此书中,大多数项目都包含单个ContentPage派生其名称是带有后缀的项目名称Page追加。In this book, most projects contain a single ContentPage derivative whose name is the name of the project with the suffix Page appended.

GreetingsPage构造函数实例化 Label 视图,它是显示文本的 Xamarin.Forms 视图。The GreetingsPage constructor instantiates a Label view, which is the Xamarin.Forms view that displays text. Text 属性设置为显示的文本LabelThe Text property is set to the text displayed by the Label. 此程序设置LabelContent属性的ContentPageThis program sets the Label to the Content property of ContentPage. 构造函数App类,然后实例化GreetingsPage并将其设置为其MainPage属性。The constructor of the App class then instantiates GreetingsPage and sets it to its MainPage property.

在页面的左上角显示的文本。The text is displayed in the upper-left corner of the page. 在 iOS 上,这意味着它与重叠页面的状态栏。On iOS, this means that it overlaps the page's status bar. 有几种解决方案,此问题:There are several solutions to this problem:

解决方案 1。Solution 1. 包括在页上的填充Include padding on the page

设置 Padding 页上的属性。Set a Padding property on the page. Padding 类型 Thickness ,具有四个属性的结构:Padding is of type Thickness, a structure with four properties:

Padding 定义页内的一个区域,其中排除内容。Padding defines an area inside a page where content is excluded. 这允许Label以避免覆盖 iOS 状态栏。This allows the Label to avoid overwriting the iOS status bar.

解决方案 2。Solution 2. 包括只适用于 iOS (仅适用于 SAP) 的填充Include padding just for iOS (SAP only)

只能在使用与 SAP 在 iOS 上设置填充属性C#预处理器指令。Set a 'Padding' property only on iOS using an SAP with a C# preprocessor directive. 了这一点 GreetingsSap 解决方案。This is demonstrated in the GreetingsSap solution.

解决方案 3。Solution 3. 包括只适用于 iOS (PCL 和 SAP) 的填充Include padding just for iOS (PCL or SAP)

在用于书的 Xamarin.Forms 版本Padding可以使用所选属性特定于 iOS 的 PCL 或 SAP Device.OnPlatform Device.OnPlatform<T> 静态方法。In the version of Xamarin.Forms used for the book, a Padding property specific to iOS in either a PCL or SAP can be selected using the Device.OnPlatform or Device.OnPlatform<T> static method. 这些方法现已弃用These methods are now deprecated

Device.OnPlatform方法用来运行特定于平台的代码,或者选择特定于平台的值。The Device.OnPlatform methods are used to run platform-specific code or to select platform-specific values. 在内部,它们使利用 Device.OS 静态只读属性,返回的成员 TargetPlatform 枚举:Internally, they make use of the Device.OS static read-only property, which returns a member of the TargetPlatform enumeration:

Device.OnPlatform方法,Device.OS属性,并TargetPlatform枚举都现在已弃用。The Device.OnPlatform methods, the Device.OS property, and the TargetPlatform enumeration are all now deprecated. 请改用 Device.RuntimePlatform 属性,并比较string返回包含以下静态字段的值:Instead, use the Device.RuntimePlatform property and compare the string return value with the following static fields:

  • iOS字符串"iOS"iOS, the string "iOS"
  • Android字符串"Android"Android, the string "Android"
  • UWP字符串"UWP",指通用 Windows 平台UWP, the string "UWP", referring to the Universal Windows Platform

Device.Idiom 静态只读属性相关联。The Device.Idiom static read-only property is related. 这将返回的成员 TargetIdiom ,其中包括以下成员:This returns a member of the TargetIdiom, which has these members:

适用于 iOS 和 Android 之间截止TabletPhone是纵向宽度为 600 的单位。For iOS and Android, the cutoff between Tablet and Phone is a portrait width of 600 units. 对于 Windows 平台中,Desktop指示在 Windows 10 下运行的 UWP 应用程序和Phone指示 Windows 10 应用程序下运行的 UWP 应用程序。For the Windows platform, Desktop indicates a UWP application running under Windows 10, and Phone indicates a UWP application running under Windows 10 application.

解决方案 3a。Solution 3a. 标签上的设置距Set margin on the Label

Margin 太迟引入属性要包含在书中,但它也是类型Thickness,并且上设置Label来定义的计算中包括视图之外的区域视图的布局。The Margin property was introduced too late to be included in the book, but it is also of type Thickness and you can set it on the Label to define an area outside the view that is included in the calculation of the view's layout.

Padding属性上才 Layout Page 派生类。The Padding property is only available on Layout and Page derivatives. Margin属性是可用于所有 View 派生类。The Margin property is available on all View derivatives.

解决方案 4。Solution 4. 在页面内的使标签居中Center the label within the page

您可以居中LabelPage(或将其放入其他 8 个位置之一) 通过设置 HorizontalOptions VerticalOptions 属性的Label为类型的值 LayoutOptions You can center the Label within the Page (or put it in one of eight other places) by setting the HorizontalOptions and VerticalOptions properties of the Label to a value of type LayoutOptions. LayoutOptions结构定义两个属性:The LayoutOptions structure defines two properties:

通常不直接使用这些属性。Generally these properties are not used directly. 相反,将这两个属性的组合提供的类型的八个静态只读属性LayoutOptions:Instead, combinations of these two properties are provided by eight static read-only properties of type LayoutOptions:

HorizontalOptionsVerticalOptions是在 Xamarin.Forms 布局中,最重要的属性和中的更详细地讨论第 4 章。滚动堆栈HorizontalOptions and VerticalOptions are the most important properties in Xamarin.Forms layout, and are discussed in more detail in Chapter 4. Scrolling the Stack.

下面是使用结果HorizontalOptionsVerticalOptions的属性Label都设置为LayoutOptions.Center:Here's the result with the HorizontalOptions and VerticalOptions properties of Label both set to LayoutOptions.Center:

Greetings 程序的三个屏幕截图Triple screenshot of greetings program

解决方案 5。Solution 5. 在标签中的文本居中Center the text within the Label

此外可以使文本居中 (或将其放在页上的其他 8 个位置中) 通过设置 HorizontalTextAlignment VerticalTextAlignment 的属性Label成员 TextAlignment 枚举:You can also center the text (or place it in eight other locations on the page) by setting the HorizontalTextAlignment and VerticalTextAlignment properties of Label to a member of the TextAlignment enumeration:

  • Start含义左或靠上 (具体取决于方向)Start, meaning left or top (depending on orientation)
  • Center
  • End这意味着右侧或底部 (取决于方向)End, meaning right or bottom (depending on orientation)

这两个属性定义仅可由Label,而HorizontalAlignmentVerticalAlignment属性定义由View并由所有继承View派生类。These two properties are defined only by Label, whereas the HorizontalAlignment and VerticalAlignment properties are defined by View and inherited by all View derivatives. 下的视觉效果可能看起来类似,但它们有很大差异,如下一章中所示。The visual results might seem similar, but they are very different as the next chapter demonstrates.