绑定值转换器

您现在知道如何使用StringFormat将任何绑定源对象转换为字符串。但是其他数据转换呢?也许您正在使用Slider作为绑定源,但目标是期望整数而不是双精度。或者您可能希望将Switch的值显示为文本,但您想要“是”和“否”而不是“真”和“假”。
这个工作的工具是一个类 - 通常是一个非常小的类 - 非正式地称为值转换器或(有时)绑定转换器。更正式地说,这样的类实现了IValueConverter接口。此接口在Xamarin.Forms命名空间中定义,但它类似于Microsoft基于XAML的环境中提供的接口。
示例:有时应用程序需要根据条目中文本的存在启用或禁用Button。也许按钮标记为保存,条目是文件名。或者按钮标记为发送,条目包含邮件收件人。除非条目包含至少一个文本字符,否则不应启用Button。
有几种方法可以完成这项工作。在后面的章节中,您将看到数据触发器如何执行它(并且还可以对条目中的文本执行有效性检查)。但是对于本章,让我们用一个值转换器来做。
数据绑定目标是Button的IsEnabled属性。该属性属于bool类型。绑定源是Entry的Text属性,或者更确切地说是Text属性的Length属性。该Length属性的类型为int。值转换器需要将int等于0转换为bool为false,将int转换为bool为true。代码很简单。我们只需要将它包装在一个实现IValueConverter的类中。
这是Xamarin.FormsBook.Toolkit库中的该类,包含using指令。 IValueConverter接口由两个方法组成,名为Convert和ConvertBack,具有相同的参数。您可以根据需要使类成为通用类或专用类:

using System;
using System.Globalization;
using Xamarin.Forms;
namespace Xamarin.FormsBook.Toolkit
{public class IntToBoolConverter : IValueConverter{public object Convert(object value, Type targetType, object parameter, CultureInfo culture){return (int)value != 0;}public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture){return (bool)value ? 1 : 0;}}
}

当您在数据绑定中包含此类时 - 您将很快看到如何执行此操作 - 只要值从源传递到目标,就会调用Convert方法。
Convert的value参数是要转换的数据绑定源的值。您可以使用GetType来确定其类型,或者您可以假设它始终是特定类型。在此示例中,假定value参数的类型为int,因此转换为int不会引发异常。更复杂的值转换器可以执行更多有效性检查。
targetType是数据绑定目标属性的类型。多功能值转换器可以使用此参数来定制不同目标类型的转换。 Convert方法应返回与此targetType匹配的对象或值。这个特殊的Convert方法假设targetType是bool。
参数参数是一个可选的转换参数,您可以将其指定为Binding类的属性。 (您将在第18章“MVVM”中看到一个示例。)
最后,如果您需要执行特定于文化的转换,则最后一个参数是您应该使用的CultureInfo对象。
此特定Convert方法的主体假定value为int,并且该方法返回bool,如果该整数非零,则为true。
ConvertBack方法仅针对TwoWay或OneWayToSource绑定调用。对于ConvertBack方法,value参数是target的值,targetType参数实际上是source属性的类型。如果您知道将永远不会调用ConvertBack方法,则可以简单地忽略所有参数并从中返回null或0。使用一些值转换器,实现ConvertBack主体实际上是不可能的,但有时它非常简单(如本例所示)。
在代码中使用值转换器时,将转换器的实例设置为Binding的Converter属性。您可以选择通过设置Binding的ConverterParameter属性将参数传递给值转换器。
如果绑定也具有StringFormat,则值转换器返回的值是格式化为字符串的值。
通常,在XAML文件中,您需要在Resources字典中实例化值转换器,然后使用StaticResource在Binding表达式中引用它。值转换器不应该保持状态,因此可以在多个绑定之间共享。
这是使用值转换器的ButtonEnabler程序:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"xmlns:toolkit="clr-namespace:Xamarin.FormsBook.Toolkit;assembly=Xamarin.FormsBook.Toolkit" x:Class="ButtonEnabler.ButtonEnablerPage"Padding="10, 50, 10, 0"><ContentPage.Resources><ResourceDictionary><toolkit:IntToBoolConverter x:Key="intToBool" /></ResourceDictionary></ContentPage.Resources> <StackLayout Spacing="20"><Entry x:Name="entry"Text=""Placeholder="text to enable button" /><Button Text="Save or Send (or something)"FontSize="Medium"HorizontalOptions="Center"IsEnabled="{Binding Source={x:Reference entry},Path=Text.Length,Converter={StaticResource intToBool}}" /></StackLayout>
</ContentPage>

IntToBoolConverter在Resources字典中实例化,并作为Button的IsEnabled属性上设置的Binding中的嵌套标记扩展引用。
请注意,Text属性在Entry标记中显式初始化为空字符串。 默认情况下,Text属性为null,这意味着Text.Length的绑定Path设置不会产生有效值。
您可能还记得以前的章节中,仅在XAML中引用的Xamarin.FormsBook.Toolkit库中的类不足以建立从应用程序到库的链接。 因此,ButtonEnabler中的App构造函数调用Toolkit.Init:

public class App : Application
{public App(){Xamarin.FormsBook.Toolkit.Toolkit.Init();MainPage = new ButtonEnablerPage();}__
}

本章中使用Xamarin.Forms Book.Toolkit库的所有程序中都会出现类似的代码。
屏幕截图确认除非条目包含一些文本,否则不会启用Button:

如果您只使用值转换器的一个实例,则无需将其存储在“资源”字典中。 您可以在Binding标记中实例化它,使用target属性的property-element标签和Binding的Converter属性:

<Button Text="Save or Send (or something)"FontSize="Large"HorizontalOptions="Center"><Button.IsEnabled><Binding Source="{x:Reference entry}"Path="Text.Length"><Binding.Converter><toolkit:IntToBoolConverter /></Binding.Converter></Binding></Button.IsEnabled>
</Button>

有时,值转换器可以方便地定义几个简单的属性。 例如,假设您要为Switch的两个设置显示一些文本,但您不想使用“True”和“False”,并且您不希望将替代值硬编码到值转换器中。 这是一个BoolToStringConverter,它包含两个文本字符串的公共属性:

namespace Xamarin.FormsBook.Toolkit
{public class BoolToStringConverter : IValueConverter{public string TrueText { set; get; }public string FalseText { set; get; }public object Convert(object value, Type targetType, object parameter, CultureInfo culture){return (bool)value ? TrueText : FalseText;}public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture){return false;}}
}

Convert方法的主体是微不足道的:它只是根据布尔值参数在两个字符串之间进行选择。
类似的值转换器将布尔值转换为两种颜色之一:

namespace Xamarin.FormsBook.Toolkit
{public class BoolToColorConverter : IValueConverter{public Color TrueColor { set; get; }public Color FalseColor { set; get; }public object Convert(object value, Type targetType, object parameter, CultureInfo culture){return (bool)value ? TrueColor : FalseColor;}public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture){return false;}}
}

SwitchText程序为两个不同的字符串对实例化BoolToStringConverter转换器两次:一次在Resources字典中,然后在Binding.Converter属性元素标记内。 最终Label的两个属性受BoolToStringConverter和BoolToColorConverter的影响,它们基于Switch的相同IsToggled属性:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"xmlns:toolkit="clr-namespace:Xamarin.FormsBook.Toolkit;assembly=Xamarin.FormsBook.Toolkit"x:Class="SwitchText.SwitchTextPage"Padding="10, 0"><ContentPage.Resources><ResourceDictionary><toolkit:BoolToStringConverter x:Key="boolToString"TrueText="Let's do it"FalseText="Not now" /><Style TargetType="Label"><Setter Property="FontSize" Value="Medium" /><Setter Property="VerticalOptions" Value="Center" /></Style></ResourceDictionary></ContentPage.Resources><StackLayout><!-- First Switch with text. --><StackLayout Orientation="Horizontal"VerticalOptions="CenterAndExpand"><Label Text="Learn more?" /><Switch x:Name="switch1"VerticalOptions="Center" /><Label Text="{Binding Source={x:Reference switch1},Path=IsToggled,Converter={StaticResource boolToString}}"HorizontalOptions="FillAndExpand" /></StackLayout><!-- Second Switch with text. --><StackLayout Orientation="Horizontal"VerticalOptions="CenterAndExpand"><Label Text="Subscribe?" /><Switch x:Name="switch2"VerticalOptions="Center" /><Label Text="{Binding Source={x:Reference switch2},Path=IsToggled,Converter={StaticResource boolToString}}"HorizontalOptions="FillAndExpand" /></StackLayout><!-- Third Switch with text and color. --><StackLayout Orientation="Horizontal"VerticalOptions="CenterAndExpand"><Label Text="Leave page?" /><Switch x:Name="switch3"VerticalOptions="Center" /><Label HorizontalOptions="FillAndExpand"><Label.Text><Binding Source="{x:Reference switch3}"Path="IsToggled"><Binding.Converter><toolkit:BoolToStringConverter TrueText="Yes"FalseText="No" /></Binding.Converter></Binding></Label.Text><Label.TextColor><Binding Source="{x:Reference switch3}"Path="IsToggled"><Binding.Converter><toolkit:BoolToColorConverter TrueColor="Green"FalseColor="Red" /></Binding.Converter></Binding></Label.TextColor></Label></StackLayout></StackLayout>
</ContentPage>

使用两个相当简单的绑定转换器,Switch现在可以显示两种状态所需的任何文本,并可以使用自定义颜色为该文本着色:

既然您已经看过BoolToStringConverter和BoolToColorConverter,您能否将该技术推广到任何类型的对象? 这是Xamarin.FormsBook.Toolkit库中的通用BoolToObjectConverter:

public class BoolToObjectConverter<T> : IValueConverter
{public T TrueObject { set; get; }public T FalseObject { set; get; }public object Convert(object value, Type targetType, object parameter, CultureInfo culture){return (bool)value ? this.TrueObject : this.FalseObject;}public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture){return ((T)value).Equals(this.TrueObject);}
}

下一个示例使用此类。

第十六章:数据绑定(七)相关推荐

  1. 第七十六章 方法关键字 - SoapAction

    文章目录 第七十六章 方法关键字 - SoapAction 用法 详情 默认 WSDL的关系 对消息的影响 第七十六章 方法关键字 - SoapAction 指定当通过HTTP将此方法作为web方法调 ...

  2. 第七十六章 SQL命令 TOP

    文章目录 第七十六章 SQL命令 TOP 大纲 参数 描述 TOP int值 TOP和缓存查询 TOP和ORDER BY TOP 优化 TOP与聚合和函数 示例 第七十六章 SQL命令 TOP 指定返 ...

  3. 鸟哥的Linux私房菜(基础篇)- 第十六章、例行性工作排程 (crontab)

    第十六章.例行性工作排程 (crontab) 最近升级日期:2009/09/11 学习了基础篇也一阵子了,你会发现到为什么系统常常会主动的进行一些任务?这些任务到底是谁在配置工作的?如果你想要让自己设 ...

  4. 第三百三十六章 斗宗强者间的大战!

    第三百三十六章 斗宗强者间的大战! <script language="javascript" src="/js/style2.js"></s ...

  5. 《Reids 设计与实现》第十六章 集群(下)

    <Reids 设计与实现>第十六章 集群(下) 文章目录 <Reids 设计与实现>第十六章 集群(下) 七.复制与故障转移 1.设置从节点 2.故障检测 3.故障转移 4.选 ...

  6. 软件项目管理第4版课后习题第十六章

    软件项目管理第4版课后习题[附解析]系列文章目录 第一章 第二章 第三章 第四章 第五章 第六章 第七章 第八章 第九章 第十章 第十一章 第十二章 第十三章 第十四章 第十五章 第十六章 期末复习题 ...

  7. 【正点原子FPGA连载】第三十六章 基于OV5640的PL以太网视频传输实验-摘自【正点原子】领航者ZYNQ之FPGA开发指南_V2.0

    1)实验平台:正点原子领航者ZYNQ开发板 2)平台购买地址:https://item.taobao.com/item.htm?&id=606160108761 3)全套实验源码+手册+视频下 ...

  8. 鸟哥的Linux私房菜(服务器)- 第十六章、文件服务器之二: SAMBA 服务器

    第十六章.文件服务器之二: SAMBA 服务器 最近更新日期:2011/07/29 如果想要共享档案,在 Linux 对 Linux 的环境下,最简单的方法就是透过 NIS 这玩意儿了!至于 Wind ...

  9. 《网络安全工程师笔记》 第十六章:OSI与TCP-IP5层协议

    注:本笔记来自温晓飞老师的网络安全课程 第十六章:OSI与TCP-IP5层协议 第一章:虚拟化架构与系统部署 第二章:IP地址详解 第三章:进制转换 第四章:DOS基本命令与批处理 第五章:用户与组管 ...

  10. C++ Primer plus学习笔记-第十六章:string类和标准模板库

    第十六章:string类和标准模板库 前言:这一章已经相当靠近全书的后面部分了:这一章我们会深入探讨一些技术上的细节,比如string的具体构造函数,比如适用于string类的几个函数,比如我们还会介 ...

最新文章

  1. Windows7上配置Python Protobuf 操作步骤
  2. ActiveMQ的消息存储和持久化
  3. 判断字符串数组中是否所有字符只出现了一次
  4. Jupyter notebook Ipython 魔法函数 Magic 计算代码(函数)耗时 Timing(%%time %time %timeit)
  5. 【python 3.6】python读取json数据存入MySQL(一)
  6. sql动态拼接<if>标签嵌套<foreach>判空、if失效等问题
  7. php 时间错误,PHP xdebug调试trace记录时间错误
  8. Dubbo基本原理机制
  9. java if两个条件_java(3) if结构
  10. 京东开通数字人民币“硬件钱包”线上消费功能
  11. aix ntp 配置_aix下开启ntp服务
  12. EL表达式和JSTL标签库学习总结
  13. epoll原理详解及epoll反应堆模型
  14. xshell连不上阿里云服务器Connection closed by foreign host.解决办法
  15. 使用liteide开发go遇到的问题
  16. PS CS6移动工具中图层与组设置快捷键切换(ps动作录制的妙用)
  17. 几组数据的相关性python_几的笔顺 笔画数:2 拼音:jī,jǐ 部首:几 - 智慧山
  18. 转载篇:RabbitMQ安装步骤和出现Plugin configuration unchanged.和出现1067系统错误.总结
  19. 两手空空也创业 没钱照样做老板
  20. 学java开发需要什么配置的电脑?

热门文章

  1. 区块链创业者:谈企业级区块链落地,传统行业的崛起(分享实录)
  2. CentOS6.5上源码安装MongoDB3.2.1
  3. eventEmitter3源码分析与学习
  4. swift笔记三 使用xcode
  5. 巧用DevExpress GridView导入导出Excel
  6. 我们如何从VC++开始“编程”?
  7. 用 Flask 来写个轻博客 (5) — (M)VC_SQLAlchemy 的 CRUD 详解
  8. Openstack 通过 SQLAlchemy-ORM 访问数据库
  9. 一个简单自激振荡器电路分析
  10. 【IntelliJ idea/My/ecplise】启动项目前,修改配置JVM参数