平淡无奇的窗体
让我们创建一个数据输入表单,让程序的用户输入一个人的姓名和其他一些信息。 当您第一次运行EntryForm程序时,它看起来像这样:
TableView包含页面上除提交按钮之外的所有内容。 这个TableView有一个TableSection,由五个单元组成 - 四个EntryCell元素和一个SwitchCell。 (这些是您尚未见过的仅有的两个Cell衍生产品。)文本“数据表单”是TableRoot对象的Title属性,它仅显示在Windows 10 Mobile屏幕上。 “个人信息”文本是TableSection的Title属性。
五个单元格对应于名为PersonalInformation的这个小类的五个属性。 虽然类名没有明确地将其标识为ViewModel,但该类派生自ViewModelBase:
class PersonalInformation : ViewModelBase
{
string name, emailAddress, phoneNumber;
int age;
bool isProgrammer;
public string Name
{
set { SetProperty(ref name, value); }
get { return name; }
}
public string EmailAddress
{
set { SetProperty(ref emailAddress, value); }
get { return emailAddress; }
}
public string PhoneNumber
{
set { SetProperty(ref phoneNumber, value); }
get { return phoneNumber; }
}
public int Age
{
set { SetProperty(ref age, value); }
get { return age; }
}
public bool IsProgrammer
{
set { SetProperty(ref isProgrammer, value); }
get { return isProgrammer; }
}
}
当您填写表单中的信息并按“提交”按钮时,程序将在屏幕底部的一个小段落中显示PersonalInformation实例中的信息:
该程序只维护一个PersonalInformation实例。 实际应用程序可能会为用户提供其信息的每个人创建一个新实例,然后将每个实例存储在ObservableCollection 中以供ListView显示。
EntryForm XAML文件将PersonalInformation实例化为TableView的BindingContext。 你可以在这里看到TableRoot,TableSection和五个Cell对象:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:EntryForm"
x:Class="EntryForm.EntryFormPage">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness"
iOS="0, 20, 0, 0" />
</ContentPage.Padding>
<StackLayout>
<TableView x:Name="tableView"
Intent="Form">
<TableView.BindingContext>
<local:PersonalInformation />
</TableView.BindingContext>
<TableRoot Title="Data Form">
<TableSection Title="Personal Information">
<EntryCell Label="Name:"
Text="{Binding Name}"
Placeholder="Enter name"
Keyboard="Text" />
<EntryCell Label="Email:"
Text="{Binding EmailAddress}"
Placeholder="Enter email address"
Keyboard="Email" />
<EntryCell Label="Phone:"
Text="{Binding PhoneNumber}"
Placeholder="Enter phone number"
Keyboard="Telephone" />
<EntryCell Label="Age:"
Text="{Binding Age}"
Placeholder="Enter age"
Keyboard="Numeric" />
<SwitchCell Text="Are you a programmer?"
On="{Binding IsProgrammer}" />
</TableSection>
</TableRoot>
</TableView>
<Label x:Name="summaryLabel"
VerticalOptions="CenterAndExpand" />
<Button Text="Submit"
HorizontalOptions="Center"
Clicked="OnSubmitButtonClicked" />
</StackLayout>
</ContentPage>
PersonalInformation类的每个属性都对应一个Cell。对于其中四个属性,这是一个EntryCell,它包含(至少在概念上)标识Label和Entry视图。 (实际上,EntryCell由特定于平台的可视对象组成,但使用Xamarin.Forms名称来说这些对象很方便。)Label属性指定出现在左侧的文本; EntryView的占位符和键盘属性在Entry中复制相同的属性。 Text属性指示Entry视图中的文本。
第五个单元是布尔属性IsProgrammer的SwitchCell。在这种情况下,Text属性指定单元格左侧的文本,On属性指示Switch的状态。
因为TableView的BindingContext是PersonalInformation,所以Cell对象中的绑定可以简单地引用PersonalInformation的属性。 EntryCell的Text属性和SwitchCell的On属性的绑定模式都是TwoWay。如果只需要将数据从视图传输到数据类,则此模式可以是OneWayToSource,但通常您可能希望从数据类初始化视图。例如,您可以在XAML文件中实例化PersonalInformation实例,如下所示:
<TableView.BindingContext>
<local:PersonalInformation Name="Naomi Name"
EmailAddress="naomi@xamarin.com"
PhoneNumber="555-1212"
Age="29"
IsProgrammer="True" />
</TableView.BindingContext>
然后在程序启动时使用该信息初始化单元格。
如果您更喜欢通过事件处理而不是数据绑定来获取信息,则EntryCell和SwitchCell都会触发事件。
代码隐藏文件只是通过使用PersonalInformation实例中的信息创建一个文本字符串并使用Label显示它来处理Submit按钮的Clicked事件:
public partial class EntryFormPage : ContentPage
{
public EntryFormPage()
{
InitializeComponent();
}
void OnSubmitButtonClicked(object sender, EventArgs args)
{
PersonalInformation personalInfo = (PersonalInformation)tableView.BindingContext;
summaryLabel.Text = String.Format(
"{0} is {1} years old, and has an email address " +
"of {2}, and a phone number of {3}, and is {4}" +
"a programmer.",
personalInfo.Name, personalInfo.Age,
personalInfo.EmailAddress, personalInfo.PhoneNumber,
personalInfo.IsProgrammer ? "" : "not ");
}
}