改变视觉效果
有时您不希望ListView显示的每个项目都以相同的格式进行格式化。 您可能希望根据某些属性的值进行一些不同的格式设置。 这通常是触发器的工作,您将在第23章中探讨。但是,您也可以使用值转换器来改变ListView中项目的视觉效果。
这是ColorCodedStudents屏幕的视图。 每个平均成绩均低于2.0的学生都会被标记为红色,这可能是为了强调需要特别注意:
从某种意义上说,这很简单:ImageCell的TextColor属性绑定到Student的GradePointAverage属性。 但这是类型为Color的属性绑定到double类型的属性,因此需要一个值转换器,并且能够对GradePointAverage属性执行测试以转换为正确的颜色。
这是Xamarin.FormsBook.Toolkit库中的ThresholdToObjectConverter:
namespace Xamarin.FormsBook.Toolkit
{
public class ThresholdToObjectConverter<T> : IValueConverter
{
public T TrueObject { set; get; }
public T FalseObject { set; get; }
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
// Code assumes that all input is valid!
double number = (double)value;
string arg = parameter as string;
char op = arg[0];
double criterion = Double.Parse(arg.Substring(1).Trim());
switch (op)
{
case '<': return number < criterion ? TrueObject : FalseObject;
case '>': return number > criterion ? TrueObject : FalseObject;
case '=': return number == criterion ? TrueObject : FalseObject;
}
return FalseObject;
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
return 0;
}
}
}
与第16章“数据绑定”中描述的BoolToObjectConverter类似,ThresholdToObjectConverter是一个泛型类,它定义了T类型的两个属性,名为TrueObject和FalseObject。 但是这个选择是基于value参数(假设是double类型)和参数参数的比较,参数参数在绑定中被指定为ConverterParameter。 假定此参数参数是包含单字符比较运算符和数字的字符串。 出于简化和清晰的目的,没有输入验证。
创建值转换器后,标记非常简单:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:school="clr-namespace:SchoolOfFineArt;assembly=SchoolOfFineArt"
xmlns:toolkit=
"clr-namespace:Xamarin.FormsBook.Toolkit;assembly=Xamarin.FormsBook.Toolkit"
x:Class="ColorCodedStudents.ColorCodedStudentsPage">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness"
iOS="0, 20, 0, 0" />
</ContentPage.Padding>
<ContentPage.Resources>
<ResourceDictionary>
<toolkit:ThresholdToObjectConverter x:Key="thresholdConverter"
x:TypeArguments="Color"
TrueObject="Default"
FalseObject="Red" />
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.BindingContext>
<school:SchoolViewModel />
</ContentPage.BindingContext>
<ListView ItemsSource="{Binding StudentBody.Students}">
<ListView.ItemTemplate>
<DataTemplate>
<ImageCell ImageSource="{Binding PhotoFilename}"
Text="{Binding FullName}"
TextColor="{Binding GradePointAverage,
Converter={StaticResource thresholdConverter},
ConverterParameter=>2}"
Detail="{Binding GradePointAverage,
StringFormat='G.P.A. = {0:F2}'}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
当GPA大于或等于2时,文本将以其默认颜色显示; 否则文本显示为红色。