项目介绍
以Notes项目为例,The Notes application consists of one solution containing four projects, as shown in the following screenshot:

The projects are:
- Notes – This project is the .NET Standard library project that holds all of the shared code and shared UI.【包含所有共享代码和共享 UI 的 .NET Standard 库项目】
- Notes.Android – This project holds Android-specific code and is the entry point for the Android application.
- Notes.iOS – This project holds iOS-specific code and is the entry point for the iOS application.
- Notes.UWP – This project holds Universal Windows Platform (UWP) specific code and is the entry point for the UWP application.
程序剖析
1、.NET Standard 库项目
包含 NuGet 和 SDK :
- NuGet–已添加到项目的 Xamarin 和 sqlite-pcl NuGet 包。
- SDK –
NETStandard.Library元包。
2、项目还包括多个文件:
- DataNoteDatabase.cs –此类包含用于创建数据库、从中读取数据、向其中写入数据和从中删除数据的代码。
- ModelsNote.cs –此类定义一个
Note模型, 其实例存储有关应用程序中每个注释的数据。 - App.xaml -
App类的 XAML 标记,该类定义应用程序的资源字典。 - App.xaml.cs -
App类的代码隐藏,该类负责实例化应用程序在每个平台上将显示的首页,并处理应用程序生命周期事件。 - AssemblyInfo.cs –此文件包含项目的应用程序属性, 该属性应用于程序集级别。
- NotesPage -
NotesPage类的 xaml 标记, 用于定义在应用程序启动时显示的页的 UI。 - NotesPage.xaml.cs -
NotesPage类的代码隐藏, 该类包含用户与页面交互时执行的业务逻辑。 - NoteEntryPage -
NoteEntryPage类的 xaml 标记, 它定义用户输入备注时显示的页面的 UI。 - NoteEntryPage.xaml.cs -
NoteEntryPage类的代码隐藏, 该类包含用户与页面交互时执行的业务逻辑。
体系结构和应用程序基础知识
共享代码通常位于 .NET Standard 库中,平台特定应用程序将使用此共享代码。

- App.xaml
若要最大限度重用启动代码,Xamarin.Forms 应用程序需有一个名为 App 的单个类,该类负责实例化应用程序在每个平台上将显示的首页【MainPage】:MainPage = new NavigationPage(new NotesPage());
- AssemblyInfo.cs
包含项目的应用程序属性。XamlCompilation特性用于控制在生成时还是运行时编译 XAML , 以便将 xaml 直接编译为中间语言。
启动应用程序
- IOS
若要在 iOS 中启动最初的Xamarin. Forms 页面, Notes.ios 项目定义了从FormsApplicationDelegate类继承的AppDelegate类。
namespace Notes.iOS { [Register("AppDelegate")] public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate { public override bool FinishedLaunching(UIApplication app, NSDictionary options) { global::Xamarin.Forms.Forms.Init(); LoadApplication(new App()); return base.FinishedLaunching(app, options); } } }
重写FinishedLaunching 方法中,通过调用Init方法来初始化 Xamarin.Forms framework ,这导致了Xamarin的ios特定实现在 根视图控制器(通过LoadApplication方法调用)之前加载。
- Android
若要在 Android 中启动最初的 Xamarin. Forms 页面, Notes.android 项目包含了一个带MainLauncher属性的Activity ,此Activity从FormsAppCompatActivity类继承:
namespace Notes.Droid { [Activity(Label = "Notes", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)] public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity { protected override void OnCreate(Bundle savedInstanceState) { TabLayoutResource = Resource.Layout.Tabbar; ToolbarResource = Resource.Layout.Toolbar; base.OnCreate(savedInstanceState); Xamarin.Essentials.Platform.Init(this, savedInstanceState); global::Xamarin.Forms.Forms.Init(this, savedInstanceState); LoadApplication(new App()); } } }
重写OnCreate方法中,通过调用Init方法来初始化 Xamarin.Forms framework ,这导致了Xamarin的android特定实现在 根视图控制器(通过LoadApplication方法调用)之前加载。
- 通用 Windows 平台(UWP)
从 App 类调用初始化 Xamarin.Forms 框架的 Init 方法(将特定于 UWP 的 Xamarin.Forms 实现加载到应用程序)
初始Xamarin.Forms页由MainPage类启动,再加载 Xamarin.Forms 应用程序(App.Xaml) 。
Universal Windows Platform apps can be built with Xamarin.Forms, but only using Visual Studio on Windows.
用户界面
有四个主要的控件组:
- 页面 - Xamarin.Forms 页呈现跨平台移动应用程序屏幕。 Notes 应用程序使用
ContentPage类(继承它)显示单个屏幕。 有关页面的详细信息,请参阅 Xamarin.Forms 页面。 - 视图 - Xamarin.Forms 视图是显示在用户界面上的控件,如标签、按钮和文本输入框,程序中对应
ListView、Editor和Button。 有关视图的详细信息,请参阅 Xamarin.Forms 视图。 - 布局 - Xamarin.Forms 布局是用于将视图组合到逻辑结构的容器。 Notes 应用程序使用
StackLayout类在垂直堆栈中排列视图和Grid类来水平排列按钮。 有关布局的详细信息,请参阅 Xamarin.Forms 布局。 - 单元格 - Xamarin.Forms 单元格是用于列表中项的专门元素,描述列表中每个项的绘制方式。 Notes 应用程序使用
TextCell为列表中的每一行显示两个项。 有关单元格的详细信息,请参阅 Xamarin.Forms 单元格。
在运行时,每个控件都会映射到其本身的本机等效项(即呈现的内容)。
- 布局
Notes 应用程序使用StackLayout来简化跨平台应用程序开发, 而不考虑屏幕大小。 根据添加顺序,以垂直方式或水平方式逐个放置每个子元素。 StackLayout 使用的空间大小取决于 HorizontalOptions 和 VerticalOptions 属性的设置方式,但默认情况下,StackLayout 尝试使用整个屏幕。
默认情况下StackLayout ,为垂直方向。 但是, 可以通过改StackLayout.Orientation属性为水平方向。
可以通过HeightRequest和WidthRequest属性设置视图的大小。
- 响应用户交互
XAML 中定义的对象可触发在cs文件中处理的事件。
导航Navigation
Xamarin.Forms 提供多种不同的页导航体验,具体取决于使用的 Page 类型。对于ContentPage实例, 导航可以是分层的, 也可以是模式。 有关模式导航的信息, 请参阅Xamarin. Forms 模式页面。
注:CarouselPage、MasterDetailPage 和 TabbedPage 类提供替代导航体验。 有关详细信息,请参阅导航。
NavigationPage
在层次结构导航【分层导航】中 NavigationPage 类用于根据需要,在ContentPage对象堆栈中向前和向后导航。 此类将导航实现为 Page 对象的后进先出 (LIFO) 堆栈。 若要从一页移动到另一页,应用程序会将新页推送到导航堆栈中,在堆栈中,该页会变为活动页。 若要返回到前一页,应用程序会从导航堆栈弹出当前页,而使最顶层的页成为活动页。
NavigationPage 类还会将一个导航栏添加到页面顶部,此导航栏包括 标题和平台相应的“返回”按钮,通过此按钮可返回上一页。
页面跳转
所有 ContentPage 实例都具有 Navigation 属性,可提供修改页面堆栈的方法,
eg,从页面跳到其他页面,await Navigation.PushAsync(new NoteEntryPage()); //这将导致NoteEntryPage新对象被推送到导航堆栈上, 并将其变成活动页。
通过设备上的返回按钮(无论是设备上的物理按钮还是屏幕按钮),可以从导航堆栈中弹出活动页。 若要以编程方式返回原始页,NoteEntryPage 对象必须调用 PopAsync 方法:await Navigation.PopAsync();
数据绑定
数据绑定在用户界面和应用程序之间建立连接。
参考:Xamarin.From中的Data binding(数据绑定)(一)
数据绑定连接两个对象,即源和目标。 源对象提供数据, 目标对象使用(并经常显示)来自源对象的数据。 例如, Editor (目标对象) 通常会将Text属性绑定到源对象中string的属性。 下图说明了这种绑定关系:

数据绑定的主要优点是让你无需再担心视图和数据源之间的数据同步。 底层的绑定框架源会将源对象中的更改自动推送到目标对象,且目标对象中的更改可选择性地推送回源对象。
建立数据绑定的过程分为两个步骤:
- 目标对象的
BindingContext属性必须设置为源。 - 必须在目标和源之间建立绑定。
实现绑定有两种方式:在xaml或者cs中
每种又分使用BindingContext与否。
1、在 XAML 中【常用方式】
不使用BingingContext:可通过使用 Binding 标记扩展实现。
在 Notes 应用程序中, 绑定目标Editor用于显示note, 而NoteEntryPage设置的绑定源。BindingContext即Note对象是
await Navigation.PushAsync(new NoteEntryPage { BindingContext = new Note() });
NoteEntryPage页面中Editor然后绑定Note对象的Text属性:
<Editor Placeholder="Enter your note" Text="{Binding Text}" ... />
在 Editor.Text 属性(目标)和源对象(Note实例)的 Text 属性之间建立绑定。 在Editor中所做的更改会自动传播到Note对象。 同样, 如果对Note.Text属性进行了更改, Xamarin 绑定引擎也将更新Editor的内容,这称为双向绑定。
使用BingingContext:
BindingContext="{x:Reference Name=slider}"
Rotation="{Binding Path=Value}"/>
小结:将Binding的Source属性或者BindingContext属性设置为x:Reference标记扩展,以引用页面上的另一个视图(源对象)。 这两个属性的类型为Object,可以将它们设置为任何包含适合于绑定源的属性的对象。
如果两者都已设置,则 Binding 的 Source 属性优先于 BindingContext。
2、只在cs中设定
需要设置以下
BindingContext属性指定源对象。SetBinding方法指定目标属性和源属性。
public BasicCodeBindingPage() { InitializeComponent(); label.BindingContext = slider; label.SetBinding(Label.RotationProperty, "Value"); }
注:若 目标和源 都是控件,则可以完全在xaml中实现绑定:
<StackLayout Padding="10, 0"> <Label x:Name="label" Text="TEXT" FontSize="80" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" BindingContext="{x:Reference Name=slider}" Rotation="{Binding Path=Value}" /> <Slider x:Name="slider" Maximum="360" VerticalOptions="CenterAndExpand" /> </StackLayout>
可以简化“基本 XAML 绑定” 页上显示的标记:XAML 标记扩展名(如 x:Reference 和 Binding)可以定义“内容属性” 属性,对于 XAML 标记扩展,这意味着不需要出现属性名称。 Name 属性是 x:Reference 的内容属性,Path 属性是 Binding 的内容属性,这意味着可以从表达式中删除它们:
<Label Text="TEXT" FontSize="80" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" BindingContext="{x:Reference slider}" Rotation="{Binding Value}" />
更多参考:基本绑定
样式Styling
Xamarin.forms应用程序通常包含多个具有相同外观的视觉元素。 设置每个视觉对象的外观可能是重复性的并且容易出错。 相反, 可以创建用于定义外观的样式, 然后将其应用于所需的视觉对象。
Style类将一些属性值分组到一个对象中, 然后可以将该对象应用于多个视觉元素实例。 样式存储在ResourceDictionary,可以针对应用程序级别、页面级别或视图级别。 使用范围如下:
Styleinstances defined at the application level can be applied throughout the application. 【应用程序级别定义的style 可以在整个应用程序中使用】Styleinstances defined at the page level can be applied to the page and to its children.【页面级别定义的style 可以在此页面或者其子页面中使用,eg: <Style TargetType="{x:Type ContentPage}"】Styleinstances defined at the view level can be applied to the view and to its children.【视图级别定义的style 可以在此视图或者子视图使用,eg:<Style TargetType="{x:Type Editor}">】
注:在整个应用程序中使用的所有样式均存储在应用程序的ResourceDictionary中, 以避免重复。 但是,XAML中的应用程序的ResourceDictionary中不应包含 用于特定于页面的Style, 因为在应用程序启动时将分析资源,而不是在页需要时进行分析。
每个Style实例都包含一个或多个Setter对象的集合。Setter每个对象都有一个Property 和一个Value。 属性是应用样式的元素的可绑定属性的名称,值是应用于属性的值。
eg:NoteEntryPage页面中的定义的Style
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Notes.NoteEntryPage" Title="Note Entry"> <ContentPage.Resources> <!-- Implicit styles --> <Style TargetType="{x:Type Editor}"> <Setter Property="BackgroundColor" Value="{StaticResource AppBackgroundColor}" /> </Style> ... </ContentPage.Resources> ... </ContentPage>
TargetType为Editor,表示NoteEntryPage页面中所有的Editor都适用于此样式。
注:除了可以使用XAMl样式,也还支持CSS样式。 请参阅设置使用级联样式表 (CSS) 的 Xamarin 应用程序样式。
提供特定于平台的样式
OnPlatform标记扩展允许你根据每个平台自定义 UI 外观:
<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Notes.App"> <Application.Resources> ... <Color x:Key="iOSNavigationBarColor">WhiteSmoke</Color> <Color x:Key="AndroidNavigationBarColor">#2196F3</Color> <Color x:Key="iOSNavigationBarTextColor">Black</Color> <Color x:Key="AndroidNavigationBarTextColor">White</Color> <Style TargetType="{x:Type NavigationPage}"> <Setter Property="BarBackgroundColor" Value="{OnPlatform iOS={StaticResource iOSNavigationBarColor}, Android={StaticResource AndroidNavigationBarColor}}" /> <Setter Property="BarTextColor" Value="{OnPlatform iOS={StaticResource iOSNavigationBarTextColor}, Android={StaticResource AndroidNavigationBarTextColor}}" /> </Style> ... </Application.Resources> </Application>