您的位置:首页 > 其它

Xamarin.Forms 简介

2017-08-10 10:28 190 查看
跨平台用户界面入门

可离线查看的 PDF

下载
PDF

相关 API:

Xamarin.Forms

你对此内容有什么想法,请告知我们

上次更新时间: 十二月 2016

Xamarin.Forms 是本机支持的跨平台抽象 UI 工具包,让开发人员能够轻松创建可在 Android、iOS、Windows 和 Windows Phone 之间共享的用户界面。 使用目标平台的本机控件即可呈现用户界面,从而让 Xamarin.Forms 应用程序为每个平台保留相应的界面外观。 本文介绍了 Xamarin.Forms 以及如何开始使用它编写应用程序。


概述

Xamarin.Forms 框架让开发人员能够快速创建跨平台用户界面。 它为用户界面提供自己的抽象,用户界面可使用 iOS、Android、Windows 或 Windows Phone 上的本机控件呈现。 这意味着应用程序可以共享大部分用户界面代码,同时保留目标平台的本机外观。

Xamarin.Forms 能让原型应用程序随时间推移迅速演变为复杂应用程序。 由于 Xamarin.Forms 应用程序是本机应用程序,因此没有其他工具包(如浏览器沙盒、API 限制或性能不佳)的限制。 使用 Xamarin.Forms 编写的应用程序能够利用基础平台的任何 API 或功能,包括(但不限于) iOS 上的 CoreMotion、PassKit 和 StoreKit;Android 上的 NFC 和 Google Play Services;以及 Windows 上的磁贴。 此外,创建应用程序时,还可以使用
Xamarin.Forms 创建应用程序用户界面的一部分,使用本机 UI 工具包创建应用程序用户界面的其他部分。

Xamarin.Forms 应用程序采用与传统跨平台应用程序相同的构建方式。 最常用的方法是使用可移植库共享项目来存放共享代码,并创建会使用共享代码的特定于平台的应用程序。

在 Xamarin.Forms 中创建用户界面可以采用两种方法。 第一种方法是完全使用 C# 源代码创建 UI。 第二种方法是使用Extensible Application Markup Language (XAML)(一种声明性标记语言)来描述用户界面。 有关 XAML 的详细信息,请参阅XAML
基础。

本文讨论 Xamarin.Forms 框架的基础知识,包括以下主题:
检查
Xamarin.Forms 应用程序。
如何使用
Xamarin.Forms 页面和控件。
如何显示数据列表
如何设置数据绑定
如何在页面之间导航
后续步骤


检查 Xamarin.Forms 应用程序

在 Xamarin Studio 和 Visual Studio 中,可以使用默认的 Xamarin.Forms 应用程序模板创建最简单的 Xamarin.Forms 解决方案,并向用户显示文本。 如果运行该应用程序,它应类似于以下屏幕截图:





屏幕截图中的每个屏幕对应于 Xamarin.Forms 中的一个页面。 
Page
 在
Android 表示为一个活动,在 iOS 中表示为一个视图控制器,在 Windows 通用平台 (UWP) 中则表示为一个页面。 以上屏幕截图中的示例实例化 
ContentPage
 对象,并使用该对象显示 
Label


为了最大限度重用启动代码,Xamarin.Forms 应用程序有一个名为 
App
 的单个类,该类负责实例化第一个将要显示的 
Page
App
 类的示例可以在以下代码中看到:
public class App : Application
{
public App ()
{
MainPage = new ContentPage {
Content =  new Label
{
Text = "Hello, Forms !",
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
}
};
}
}
[/code]

此代码实例化一个新的 
ContentPage
 对象,该对象将在页面上垂直和水平居中显示单个 
Label



在每个平台上启动 Xamarin.Forms 初始页面

若要在应用程序内部使用此 
Page
,每个平台应用程序启动时必须初始化
Xamarin.Forms 框架并提供 
ContentPage
 的一个实例。
初始化步骤因平台而异,此内容将在以下部分讨论。


iOS

若要在 iOS 中启动 Xamarin.Forms 初始页面,平台项目应包括 
AppDelegate
 类(该类从
Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
 类继承),如以下代码示例所示:
[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);
}
}
[/code]

通过调用 
Init
 方法,
FinishedLoading
 替代初始化 Xamarin.Forms 框架。 这会导致在调用将根视图控制器设置为
LoadApplication
 方法之前,将特定于
iOS 的 Xamarin.Forms 实现加载到应用程序。


Android

若要在 Android 中启动 Xamarin.Forms 初始页面,平台项目应包括可使用 
MainLauncher
 属性创建 
Activity
 的代码,且具有从 
FormsApplicationActivity
 类继承的活动,如以下代码示例所示:
namespace HelloXamarinFormsWorld.Android
{
[Activity(Label = "HelloXamarinFormsWorld", MainLauncher = true,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication (new App ());
}
}
}
[/code]

通过调用 
Init
 方法,
OnCreate
 替代初始化 Xamarin.Forms 框架。 这会导致在加载 Xamarin.Forms
应用程序之前,将特定于 Android 的 Xamarin.Forms 实现加载到应用程序。


Windows Phone 8.1 (WinRT)

在 Windows 运行时应用程序中,可从 
App
 类调用初始化 Xamarin.Forms 框架的 
Init
 方法:
Xamarin.Forms.Forms.Init (e);

if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
...
}
[/code]

这会将特定于 Windows Phone 的 Xamarin.Forms 实现加载到应用程序中。 可通过 
MainPage
 类启动 Xamarin.Forms 初始页面,如以下代码示例所示:
public partial class MainPage
{
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
this.LoadApplication(new HelloXamarinFormsWorld.App());
}
}
[/code]

可通过 
LoadApplication
 方法加载 Xamarin.Forms 应用程序。

Xamarin.Forms 还支持 Windows 8.1。 有关如何配置此项目类型的信息,请参阅设置
Windows 项目。


通用 Windows 平台

在通用 Windows 平台 (UWP) 应用程序中,可从 
App
 类调用初始化 Xamarin.Forms 框架的 
Init
 方法:
Xamarin.Forms.Forms.Init (e);

if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
...
}
[/code]

这会将特定于 UWP 的 Xamarin.Forms 实现加载到应用程序。 可通过 
MainPage
 类启动 Xamarin.Forms 初始页面,如以下代码示例所示:
public partial class MainPage
{
public MainPage()
{
this.InitializeComponent();
this.LoadApplication(new HelloXamarinFormsWorld.App());
}
}
[/code]

可通过 
LoadApplication
 方法加载 Xamarin.Forms 应用程序。


视图和布局

可使用 4 个主要控件组创建 Xamarin.Forms 应用程序的用户界面。
页面 - Xamarin.Forms 页呈现跨平台移动应用程序屏幕。 有关页面的详细信息,请参阅 Xamarin.Forms
页面。
布局 - Xamarin.Forms 布局是用于将视图组合到逻辑结构的容器。 有关布局的详细信息,请参阅 Xamarin.Forms
布局。
视图 - Xamarin.Forms 视图是显示在用户界面上的控件,如标签、按钮和文本输入框。 有关视图的详细信息,请参阅Xamarin.Forms
视图。
单元格 - Xamarin.Forms 单元格是专门用于列表中的项的元素,描述列表中每个项的绘制方式。 有关单元格的详细信息,请参阅 Xamarin.Forms
单元格。

在运行时,每个控件都会映射到其本身的本机等效项(即呈现的内容)。

控件在布局内部进行托管。 现在检查 
StackLayout
 类,该类实现常用的布局。


StackLayout

StackLayout
 在屏幕上自动排列控件而不考虑屏幕大小,从而简化了跨平台应用程序开发。
根据添加顺序,以垂直方式或水平方式逐个放置每个子元素。 
StackLayout
 使用的空间大小取决于 
HorizontalOptions
 和 
VerticalOptions
 属性的设置方式,但默认情况下,
StackLayout
 尝试使用整个屏幕。

以下 XAML 代码举例说明了如何使用 
StackLayout
 排列三个 
Label
 控件:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="HelloXamarinFormsWorldXaml.StackLayoutExample1" Padding="20">
<StackLayout Spacing="10">
<Label Text="Stop" BackgroundColor="Red" Font="20" />
<Label Text="Slow down" BackgroundColor="Yellow" Font="20" />
<Label Text="Go" BackgroundColor="Green" Font="20" />
</StackLayout>
</ContentPage>
[/code]

以下代码示例显示相应的 C# 代码:
public class StackLayoutExample : ContentPage
{
public StackLayoutExample()
{
Padding = new Thickness(20);
var red = new Label
{
Text = "Stop", BackgroundColor = Color.Red, FontSize = 20
};
var yellow = new Label
{
Text = "Slow down", BackgroundColor = Color.Yellow, FontSize = 20
};
var green = new Label
{
Text = "Go", BackgroundColor = Color.Green, FontSize = 20
};

Content = new StackLayout
{
Spacing = 10,
Children = { red, yellow, green }
};
}
}
[/code]

默认情况下,
StackLayout
 采用垂直方向,如以下屏幕截图所示:





可以将 
StackLayout
 更改为水平方向,如以下
XAML 代码示例所示:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="HelloXamarinFormsWorldXaml.StackLayoutExample2" Padding="20">
<StackLayout Spacing="10" VerticalOptions="End" Orientation="Horizontal" HorizontalOptions="Start">
<Label Text="Stop" BackgroundColor="Red" Font="20" />
<Label Text="Slow down" BackgroundColor="Yellow" Font="20" />
<Label Text="Go" BackgroundColor="Green" Font="20" />
</StackLayout>
</ContentPage>
[/code]

以下代码示例显示相应的 C# 代码:
public class StackLayoutExample: ContentPage
{
public StackLayoutExample()
{
// Code that creates labels removed for clarity
Content = new StackLayout
{
Spacing = 10,
VerticalOptions = LayoutOptions.End,
Orientation = StackOrientation.Horizontal,
HorizontalOptions = LayoutOptions.Start,
Children = { red, yellow, green }
};
}
}
[/code]

以下屏幕截图显示布局结果:





可通过 
HeightRequest
 和 
WidthRequest
 属性设置控件大小,如以下 XAML 代码示例所示:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="HelloXamarinFormsWorldXaml.StackLayoutExample3" Padding="20">
<StackLayout Spacing="10" VerticalOptions="End" Orientation="Horizontal" HorizontalOptions="Start">
<Label Text="Stop" BackgroundColor="Red" Font="20" WidthRequest="100" />
<Label Text="Slow down" BackgroundColor="Yellow" Font="20" WidthRequest="100" />
<Label Text="Go" BackgroundColor="Green" Font="20" WidthRequest="200" />
</StackLayout>
</ContentPage>
[/code]

以下代码示例显示相应的 C# 代码:
var red = new Label
{
Text = "Stop", BackgroundColor = Color.Red, FontSize = 20, WidthRequest = 100
};
var yellow = new Label
{
Text = "Slow down", BackgroundColor = Color.Yellow, FontSize = 20, WidthRequest = 100
};
var green = new Label
{
Text = "Go", BackgroundColor = Color.Green, FontSize = 20, WidthRequest = 200
};

Content = new StackLayout
{
Spacing = 10,
VerticalOptions = LayoutOptions.End,
Orientation = StackOrientation.Horizontal,
HorizontalOptions = LayoutOptions.Start,
Children = { red, yellow, green }
};
[/code]

以下屏幕截图显示布局结果:





有关 
StackLayout
 类的详细信息,请参阅 StackLayout


Xamarin.Forms 中的列表

ListView
 控件负责在屏幕上显示项集合
ListView
 中的每一个项都包含在单个单元格中。 默认情况下,
ListView
 使用内置
TextCell
 模板并呈现单行文本。

以下代码示例演示一个简单的 
ListView
 示例:
var listView = new ListView
{
RowHeight = 40
};
listView.ItemsSource = new string []
{
"Buy pears", "Buy oranges", "Buy mangos", "Buy apples", "Buy bananas"
};
Content = new StackLayout
{
VerticalOptions = LayoutOptions.FillAndExpand,
Children = { listView }
};
[/code]

以下屏幕截图显示生成的 
ListView




有关 
ListView
 控件的详细信息,请参阅 ListView


绑定到自定义类

ListView
 控件还可以通过默认的 
TextCell
 模板显示自定义对象。

以下代码示例演示 
TodoItem
 类:
public class TodoItem
{
public string Name { get; set; }
public bool Done { get; set; }
}
[/code]

可按如下代码示例所示填充 
ListView
 控件:
listView.ItemsSource = new TodoItem [] {
new TodoItem { Name = "Buy pears" },
new TodoItem { Name = "Buy oranges", Done=true} ,
new TodoItem { Name = "Buy mangos" },
new TodoItem { Name = "Buy apples", Done=true },
new TodoItem { Name = "Buy bananas", Done=true }
};
[/code]

可以创建一个绑定以设置 
ListView
 要显示的 
TodoItem
 属性类型,如以下代码示例所示:
listView.ItemTemplate = new DataTemplate(typeof(TextCell));
listView.ItemTemplate.SetBinding(TextCell.TextProperty, "Name");
[/code]

这会创建一个绑定,指定 
TodoItem.Name
 属性的路径,并生成前面显示的屏幕截图。

有关绑定到自定义类的详细信息,请参阅 ListView
数据源。


选择 ListView 中的项

为响应用户触摸 
ListView
 中的单元格,应处理 
ItemSelected
 事件,如以下代码示例所示:
listView.ItemSelected += async (sender, e) => {
await DisplayAlert("Tapped!", e.SelectedItem + " was tapped.", "OK");
};
[/code]

当包含在 
NavigationPage
 中时,
PushAsync
 方法可用来打开具有内置后退导航的新页面。 
ItemSelected
 事件可以访问通过
e.SelectedItem
 属性与单元格关联的对象,将其绑定到新页面并使用 
PushAsync
 显示新页面,如以下代码示例所示:
listView.ItemSelected += async (sender, e) => {
var todoItem = (TodoItem)e.SelectedItem;
var todoPage = new TodoItemPage(todoItem); // so the new page shows correct data
await Navigation.PushAsync(todoPage);
};
[/code]

每个平台实现内置后退导航的方法都各不相同。 有关详细信息,请参阅导航

有关 
ListView
 选择的详细信息,请参阅 ListView
交互性。


自定义单元格的外观

通过子类化 
ViewCell
 类,并将该类的类型设置为 
ListView
 的 
ItemTemplate
 属性,可以自定义单元格的外观。

以下屏幕截图所示的单元格由一个 
Image
 和两个 
Label
 控件组成:



若要创建此自定义布局,应子类化 
ViewCell
 类,如以下代码示例所示:
class EmployeeCell : ViewCell
{
public EmployeeCell()
{
var image = new Image
{
HorizontalOptions = LayoutOptions.Start
};
image.SetBinding(Image.SourceProperty, new Binding("ImageUri"));
image.WidthRequest = image.HeightRequest = 40;

var nameLayout = CreateNameLayout();
var viewLayout = new StackLayout()
{
Orientation = StackOrientation.Horizontal,
Children = { image, nameLayout }
};
View = viewLayout;
}

static StackLayout CreateNameLayout()
{
var nameLabel = new Label
{
HorizontalOptions= LayoutOptions.FillAndExpand
};
nameLabel.SetBinding(Label.TextProperty, "DisplayName");

var twitterLabel = new Label
{
HorizontalOptions = LayoutOptions.FillAndExpand,
Font = Fonts.Twitter
};
twitterLabel.SetBinding(Label.TextProperty, "Twitter");

var nameLayout = new StackLayout()
{
HorizontalOptions = LayoutOptions.StartAndExpand,
Orientation = StackOrientation.Vertical,
Children = { nameLabel, twitterLabel }
};
return nameLayout;
}
}
[/code]

此段代码执行下列任务:
添加 
Image
 控件并将其绑定到 
Employee
 对象的 
ImageUri
 属性。
若要深入了解数据绑定,请参阅数据绑定
创建垂直方向的 
StackLayout
 来存放两个 
Label
 控件。 
Label
 控件被绑定到 
DisplayName
 和 
Employee
 对象的 
Twitter
 属性。
创建 
StackLayout
用于托管现有的 
Image
 和 
StackLayout

使用水平方向排列其子级。

创建好自定义单元格后,可以通过将其包装在 
DataTemplate
 中由 
ListView
 控件使用,如以下代码示例所示:
List<Employee> myListOfEmployeeObjects = GetAListOfAllEmployees();
var listView = new ListView
{
RowHeight = 40
};
listView.ItemsSource = myListOfEmployeeObjects;
listView.ItemTemplate = new DataTemplate(typeof(EmployeeCell));
[/code]

此代码为 
ListView
 提供 
Employee
 的 
List

可使用 
EmployeeCell
 类呈现每个单元格。 
ListView
 将 
Employee
 对象作为其
BindingContext
 传递给 
EmployeeCell


有关自定义单元格的外观的详细信息,请参阅单元格的外观


使用 XAML 创建和自定义列表

以下代码示例演示上一部分中 
ListView
 的
XAML 等效项:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:XamarinFormsXamlSample;assembly=XamarinFormsXamlSample"
xmlns:constants="clr-namespace:XamarinFormsSample;assembly=XamarinFormsXamlSample"
x:Class="XamarinFormsXamlSample.Views.EmployeeListPage"
Title="Employee List">
<ListView x:Name="listView" IsVisible="false" ItemsSource="{x:Static local:App.Employees}" ItemSelected="EmployeeListOnItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<StackLayout Orientation="Horizontal">
<Image Source="{Binding ImageUri}" WidthRequest="40" HeightRequest="40" />
<StackLayout Orientation="Vertical" HorizontalOptions="StartAndExpand">
<Label Text="{Binding DisplayName}" HorizontalOptions="FillAndExpand" />
<Label Text="{Binding Twitter}" Font="{x:Static constants:Fonts.Twitter}"/>
</StackLayout>
</StackLayout>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
[/code]

此 XAML 定义包含 
ListView
 的 
ContentPage

可通过 
ItemsSource
 属性设置 
ListView
 的数据源。
ListView.ItemTemplate
 元素内定义 
ItemsSource
 中每一行的布局。


数据绑定

数据绑定连接两个对象,即源和目标。 源对象提供数据。 目标对象使用(并经常显示)来自源对象的数据。 例如,
Label
(目标对象)通常会将其 
Text
 属性绑定到源对象中的公共 
string
 属性。
下图说明了这种绑定关系:



数据绑定的主要优点是让你无需再担心视图和数据源之间的数据同步。 幕后的绑定框架源会将源对象中的更改自动推送到目标对象,且目标对象中的更改可选择性地推送回源对象。

创建数据绑定只需两个步骤:
目标对象的 
BindingContext
 属性必须设置为源。
必须在目标和源之间建立绑定。 在 XAML 中,此过程可通过使用 
Binding
 标记扩展实现。
在 C# 中,此过程可通过
SetBinding
 方法实现。

若要深入了解数据绑定,请参阅数据绑定基本知识


XAML

以下代码示例说明如何在 XAML 中执行数据绑定:
<Entry Text="{Binding FirstName}" ... />
[/code]

在 
Entry.Text
 属性和源
对象的 
FirstName
 属性之间建立绑定。 
Entry
 控件中所做的更改将自动传播到 
employeeToDisplay
对象。
同样,如果更改了 
employeeToDisplay.FirstName
 属性,Xamarin.Forms 绑定引擎也会更新 
Entry
 控件的内容。
这称为双向绑定。 为了使双向绑定发挥作用,模型类必须实现 
INotifyPropertyChanged
 接口。

尽管可以在 XAML 中设置 
EmployeeDetailPage
 类的 
BindingContext
 属性,但此处在代码隐藏中设置 
Employee
 对象的实例:
public EmployeeDetailPage(Employee employee)
{
InitializeComponent();
this.BindingContext = employee;
}
[/code]

虽然可以分别设置每个目标对象的 
BindingContext
 属性,但没有必要。 
BindingContext
 是特殊属性,其所有子级都会继承该属性。
因此,当 
ContentPage
 上的 
BindingContext
 设置为 
Employee
 实例时,
ContentPage
 的所有子级都具有相同的
BindingContext
,并且都可绑定到 
Employee
 对象的公共属性。


C#

以下代码示例说明如何在 C# 中执行数据绑定:
public EmployeeDetailPage(Employee employeeToDisplay)
{
this.BindingContext = employeeToDisplay;
var firstName = new Entry()
{
HorizontalOptions = LayoutOptions.FillAndExpand
};
firstName.SetBinding(Entry.TextProperty, "FirstName");
...
}
[/code]

向 
ContentPage
 构造函数传递 
Employee
 对象的一个实例,并将 
BindingContext
 设置为要绑定到的对象。
实例化 
Entry
 控件,并在 
Entry.Text
 属性和源对象的 
FirstName
 属性之间设置绑定。 
Entry
 控件中所做的更改将自动传播到
employeeToDisplay
 对象。
同样,如果更改了 
employeeToDisplay.FirstName
 属性,Xamarin.Forms 绑定引擎也会更新 
Entry
控件的内容。
这称为双向绑定。 为了使双向绑定发挥作用,模型类必须实现 
INotifyPropertyChanged
 接口。

SetBinding
 方法采用两个参数。 第一个参数指定绑定类型的信息。 第二个参数提供绑定内容或绑定方式的信息。 大多数情况下,第二个参数只是一个字符串,持有 
BindingContext
 上的属性名称。
使用下列语法可直接绑定到 
BindingContext

someLabel.SetBinding(Label.TextProperty, new Binding("."));
[/code]

使用点语法指示 Xamarin.Forms 使用 
BindingContext
(而非 
BindingContext
 上的属性)作为数据源。
如果 
BindingContext
是简单类型(例如 
string
 或 
int
),此语法非常有用。


属性更改通知

创建绑定后,默认情况下目标对象只接收源对象的值。 若要使 UI 与数据源同步,当源对象发生更改时,必须通过一种方法来通知目标对象。 
INotifyPropertyChanged
 接口就提供了这种机制。 当基础属性值发生更改时,实现此接口可以通知任何数据绑定控件。

当它的某个属性更新为新值时,实现 
INotifyPropertyChanged
 的对象必须引发 
PropertyChanged
 事件,如以下代码示例所示:
public class MyObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;

string _firstName;
public string FirstName
{
get { return _firstName; }
set
{
if (value.Equals(_firstName, StringComparison.Ordinal))
{
// Nothing to do - the value hasn't changed;
return;
}
_firstName = value;
OnPropertyChanged();

}
}

void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
[/code]

当 
MyObject.FirstName
 属性发生更改时,会调用 
OnPropertyChanged
 法,从而引发 
PropertyChanged
 事件。
为了避免不必要的事件触发,如果属性值没有发生更改,则不引发 
PropertyChanged
 事件。

请注意,在 
OnPropertyChanged
 方法中,
propertyName
 参数标有 
CallerMemberName
 属性。
这可确保当使用 
null
 值调用
OnPropertyChanged
 方法时,
CallerMemberName
 属性提供调用 
OnPropertyChanged
 的方法的名称。


导航

Xamarin.Forms 提供多种不同的页导航体验,具体取决于使用的 
Page
 类型。
对于 
ContentPage
 实例,提供两种导航体验:
分层导航
模式导航

CarouselPage
MasterDetailPage
 和 
TabbedPage
 类提供替代导航体验。
有关详细信息,请参阅导航


分层导航

NavigationPage
 类提供分层导航体验,用户可以随心所欲地向前或向后导航页面。
此类将导航实现为 
Page
 对象的后进先出
(LIFO) 堆栈。

在分层导航中,使用 
NavigationPage
 类在 
ContentPage
 对象的堆栈内进行导航。
若要从一页移动到另一页,应用程序会将新页推送到导航堆栈中,在堆栈中,该页会变为活动页。 若要返回到前一页,应用程序会从导航堆栈弹出当前页,而使最顶层的页成为活动页。

添加到导航堆栈中的第一页称为应用程序的根页,以下代码示例显示了实现此过程的方法:
public App ()
{
MainPage = new NavigationPage(new EmployeeListPage());
}
[/code]

若要导航到 
LoginPage
,需要调用当前页的 
Navigation
 属性上的 
PushAsync
 方法,如以下代码示例所示:
await Navigation.PushAsync(new LoginPage());
[/code]

这会将新的 
LoginPage
 对象推送到导航堆栈中,在堆栈中,它成为活动页。

通过设备上的返回按钮(无论是设备上的物理按钮还是屏幕按钮),可以从导航堆栈中弹出活动页。 若要以编程方式返回到前一页,
LoginPage
 实例必须调用 
PopAsync
 方法,如以下代码示例所示:
await Navigation.PopAsync();
[/code]

有关分层导航的详细信息,请参阅分层导航


模式导航

Xamarin.Forms 支持模式页面。 模式页面鼓励用户完成独立任务,在完成或取消该任务之前,不允许导航离开该任务。

模式页面可以是 Xamarin.Forms 支持的任何 
Page
 类型。
若要显示模式页面,应用程序会将页面推送到导航堆栈中,在堆栈中,该页会变为活动页。 若要返到回前一页,应用程序会从导航堆栈弹出当前页面,而使最顶层的页成为活动页。

可以由任何 
Page
 派生类型上的 
Navigation
 属性公开模式导航方法。
也可使用 
Navigation
 属性公开 
ModalStack
 属性,并从中获得导航堆栈中的模式页面。
但是,在模式导航中没有执行模式堆栈操作或弹出到根页的概念。 这是因为基础平台普遍都不支持这些操作。

执行模式页面导航无需具有 
NavigationPage
 实例。

若要以模式方式导航到 
LoginPage
,需要调用当前页的 
Navigation
 属性上的 
PushModalAsync
 方法,如以下代码示例所示:
await Navigation.PushModalAsync(new LoginPage());
[/code]

这会将 
LoginPage
 实例推送到导航堆栈中,在堆栈中,它成为活动页。

通过设备上的返回按钮(无论是设备上的物理按钮还是屏幕按钮),可以从导航堆栈中弹出活动页。 若要以编程方式返回原始页,
LoginPage
 实例必须调用 
PopModalAsync
 方法,如以下代码示例所示:
await Navigation.PopModalAsync();
[/code]

这会从导航堆栈中删除 
LoginPage
 实例,而使最顶层的页成为活动页。

有关模式导航的详细信息,请参阅模式页面


后续步骤

本文介绍了如何开始编写 Xamarin.Forms 应用程序。 建议的后续步骤包括了解以下功能:
控件模板让你在运行时能够轻松设计或重新设计应用程序页面的主题。 有关详细信息,请参阅控件模板
数据模板让你可以在支持的控件上定义数据表示形式。 有关详细信息,请参阅数据模板
共享代码可通过 
DependencyService
 类访问本机功能。
有关详细信息,请参阅通过 DependencyService 访问本机功能
Xamarin.Forms 具有简单的消息传送服务,用于发送和接收消息,减少两个类之间的耦合。 有关详细信息,请参阅通过
MessagingCenter 发布和订阅。
通过 
Renderer
 类可以在每个平台上以不同方式呈现每个页面、布局和控件,反过来又可以创建本机控件,在屏幕上排列该控件,并添加共享代码中指定的行为。 开发人员可以实现自定义 
Renderer
 类,以自定义控件的外观和/或行为。
有关详细信息,请参阅自定义呈现器
还可以自定义每个平台上的本机控件的效果。 通过子类化 
PlatformEffect
 控件在特定于平台的项目中创建效果,并将其附加到相应的
Xamarin.Forms 控件中使用。 有关详细信息,请参阅效果

此外,也可以阅读 Charles Petzold 撰写的 Creating Mobile Apps with Xamarin.Forms(使用 Xamarin.Forms 创建移动应用),了解有关 Xamarin.Forms 的详细信息。 有关详细信息,请参阅使用
Xamarin.Forms 创建移动应用。


摘要

本文介绍了 Xamarin.Forms 以及如何开始使用它编写应用程序。 Xamarin.Forms 是本机支持的跨平台抽象 UI 工具包,让开发人员能够轻松创建可在 Android、iOS、Windows 和 Windows Phone 之间共享的用户界面。 使用目标平台的本机控件即可呈现用户界面,从而让 Xamarin.Forms 应用程序为每个平台保留相应的界面外观。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  xamarin xamarin.forms