条件部分
TableView可以有多个部分,如果当前不适用,您可能希望部分完全不可见。 在前面的示例中,标题为“Programmer Information”的第二部分可能包含Language和Platform属性的两个PickerCell元素。 要使该部分可见或隐藏,可以根据IsProgrammer属性的设置将该部分添加到TableRoot中或从TableRoot中删除。 (回想一下,TableView中的内部集合属于ObservableCollection类型,因此TableView应该响应从这些集合中动态添加或删除的项。)不幸的是,这不能完全在XAML中处理,但代码支持相当容易。
这是ConditionalSection程序中的XAML文件。 它与前一个程序中的XAML文件相同,只是不再在TableView上设置BindingContext(在代码隐藏文件中发生),最后两个PickerCell元素已被移动到第二个部分,标题为“ 程序员信息“:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:ConditionalSection"
xmlns:toolkit=
"clr-namespace:Xamarin.FormsBook.Toolkit;assembly=Xamarin.FormsBook.Toolkit"
x:Class="ConditionalSection.ConditionalSectionPage">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness"
iOS="0, 20, 0, 0" />
</ContentPage.Padding>
<StackLayout>
<TableView x:Name="tableView"
Intent="Form">
<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" />
<toolkit:PickerCell Label="Age Range:"
Title="Age Range"
SelectedValue="{Binding AgeRange}">
<x:String>10 - 19</x:String>
<x:String>20 - 29</x:String>
<x:String>30 - 39</x:String>
<x:String>40 - 49</x:String>
<x:String>50 - 59</x:String>
<x:String>60 - 99</x:String>
</toolkit:PickerCell>
<SwitchCell x:Name="isProgrammerSwitch"
Text="Are you a programmer?"
On="{Binding IsProgrammer}" />
</TableSection>
<TableSection x:Name="programmerInfoSection"
Title="Programmer Information">
<toolkit:PickerCell Label="Language:"
Title="Language"
SelectedValue="{Binding Language}">
<x:String>C</x:String>
<x:String>C++</x:String>
<x:String>C#</x:String>
<x:String>Objective C</x:String>
<x:String>Java</x:String>
<x:String>Other</x:String>
</toolkit:PickerCell>
<toolkit:PickerCell Label="Platform:"
Title="Platform"
SelectedValue="{Binding Platform}">
<x:String>iPhone</x:String>
<x:String>Android</x:String>
<x:String>Windows Phone</x:String>
<x:String>Other</x:String>
</toolkit:PickerCell>
</TableSection>
</TableRoot>
</TableView>
</StackLayout>
</ContentPage>
代码隐藏文件中的构造函数处理其余部分。 它创建ProgrammerInformation对象以设置为TableView的BindingContext,然后从TableRoot中删除第二个TableSection。 然后,页面构造函数为ProgrammerInformation的PropertyChanged事件设置处理程序,并等待对IsProgrammer属性的更改:
public partial class ConditionalSectionPage : ContentPage
{
public ConditionalSectionPage()
{
InitializeComponent();
// Set BindingContext of TableView.
ProgrammerInformation programmerInfo = new ProgrammerInformation();
tableView.BindingContext = programmerInfo;
// Remove programmer-information section!
tableView.Root.Remove(programmerInfoSection);
// Watch for changes in IsProgrammer property in ProgrammerInformation.
programmerInfo.PropertyChanged += (sender, args) =>
{
if (args.PropertyName == "IsProgrammer")
{
if (programmerInfo.IsProgrammer &&
tableView.Root.IndexOf(programmerInfoSection) == -1)
{
tableView.Root.Add(programmerInfoSection);
}
if (!programmerInfo.IsProgrammer &&
tableView.Root.IndexOf(programmerInfoSection) != -1)
{
tableView.Root.Remove(programmerInfoSection);
}
}
};
}
}
理论上,PropertyChanged处理程序在添加之前不需要检查TableSection是否已经是TableRoot集合的一部分,或者在尝试删除它之前检查它是否不是集合的一部分,但是检查不会受到影响。
这是程序首次启动时只有一个部分可见:
切换SwitchCell会使另外两个属性进入视图:
但不是在Windows 10 Mobile屏幕上。
您不需要为整个TableView使用单个BindingContext。 每个TableSection都有自己的BindingContext,这意味着您可以将ViewModel划分为与TableView布局更紧密地协调。