只读可绑定属性
假设您正在使用一个应用程序,在该应用程序中,可以方便地知道Label元素显示的文本中的单词数。 也许您希望将该工具直接构建到源自Label的类中。 我们称这个新类为CountedLabel。
到目前为止,您首先想到的是定义一个名为WordCount?属性的BindableProperty对象和一个名为WordCount的相应CLR属性。
但是等一下:只有从CountedLabel类中设置这个WordCount属性才有意义。 这意味着WordCount CLR属性不应具有公共集访问器。 它应该这样定义:

public int WordCount
{private set { SetValue(WordCountProperty, value); }get { return (double)GetValue(WordCountProperty); }
}

get访问器仍然是公共的,但set访问器是私有的。 那够了吗?
不完全是。 尽管CLR属性中有私有set访问器,但CountedLabel外部的代码仍然可以使用CountedLabel.WordCountProperty可绑定属性对象调用SetValue。 这种类型的财产设置也应该被禁止。 但是,如果WordCountProp?erty对象是公共的,那怎么能工作呢?
解决方案是使用BindableProperty.Create?ReadOnly方法创建只读的可绑定属性。 Xamarin.Forms API本身定义了几个只读的可绑定属性 - 例如,Width和
由VisualElement定义的高度属性。
以下是如何制作自己的:
第一步是使用与BindableProperty.Create相同的参数调用BindableProperty.CreateReadOnly。 但是,CreateReadOnly方法返回Binda?blePropertyKey的对象而不是BindableProperty。 将此对象定义为static和readonly,与BindableProperty一样,但将其设置为类的私有:


public class CountedLabel : Label
{static readonly BindablePropertyKey WordCountKey =BindableProperty.CreateReadOnly("WordCount", //propertyNametypeof(int), // returnTypetypeof(CountedLabel), // declaringType0); // defaultValue}

不要将此BindablePropertyKey对象视为加密密钥或类似的东西。 它更简单 - 实际上只是一个私有的对象。
第二步是使用BindablePropertyKey的BindableProperty属性创建一个公共BindableProperty对象:

public class CountedLabel : Label
{public static readonly BindableProperty WordCountProperty = WordCountKey.BindableProperty;}

这个BindableProperty对象是公共的,但它是一种特殊的BindableProperty:它不能用于SetValue调用。 尝试这样做会引发InvalidOperationException。
但是,SetValue方法有一个重载,它接受一个BindablePropertyKey对象。 CLR set访问器可以使用此对象调用SetValue,但是此set访问器必须是私有的,以防止在类外部设置属性:

public class CountedLabel : Label
{public int WordCount{private set { SetValue(WordCountKey, value); }get { return (int)GetValue(WordCountProperty); }}}

现在可以在CountedLabel类中设置WordCount属性。 但课程什么时候应该设定呢? 此CountedLabel类派生自Label,但它需要检测Text prop?erty何时更改,以便它可以对单词进行计数。
Label有TextChanged事件吗? 不,不是的。 但是,BindableObject实现了INotifyPropertyChanged接口。 这是一个非常重要的.NET接口,特别是对于实现Model-View-ViewModel(MVVM)体系结构的应用程序。 在第18章中,您将了解如何在自己的数据类中使用它。
INotifyPropertyChanged接口在System.ComponentModel命名空间中定义,如下所示:

public interface INotifyPropertyChanged
{event PropertyChangedEventHandler PropertyChanged;
}

每当由BindableProperty支持的任何属性发生更改时,从BindableObject派生的每个类都会自动触发此PropertyChanged事件。 此事件附带的PropertyChangedEventArgs对象包含一个名为PropertyName的属性,其属性为string,用于标识已更改的属性。
因此,所有必要的是,CountedLabel为PropertyChanged事件附加处理程序并检查属性名称“Text”。 从那里它可以使用它想要的任何技术来计算字数。 完整的CountedLabel类在PropertyChanged事件上使用lambda函数。 处理程序调用Split将字符串分解为单词,并查看有多少部分结果。 Split方法基于空格,短划线和短划线(Unicode u2014)拆分文本:

public class CountedLabel : Label
{static readonly BindablePropertyKey WordCountKey =BindableProperty.CreateReadOnly("WordCount", // propertyNametypeof(int), // returnTypetypeof(CountedLabel), // declaringType0); // defaultValuepublic static readonly BindableProperty WordCountProperty = WordCountKey.BindableProperty;public CountedLabel(){// Set the WordCount property when the Text property changes.PropertyChanged += (object sender, PropertyChangedEventArgs args) =>{if (args.PropertyName == "Text"){if (String.IsNullOrEmpty(Text)){WordCount = 0;}else{WordCount = Text.Split(' ', '-', '\u2014').Length;}}};}public int WordCount{private set { SetValue(WordCountKey, value); }get { return (int)GetValue(WordCountProperty); }}
}

该类包含System.ComponentModel命名空间的using指令,用于处理程序的Property?ChangedEventArgs参数。 注意:Xamarin.Forms定义了一个名为Prop?ertyChangingEventArgs(现在时)的类。 这不是你想要的PropertyChanged han?dler。 你想要PropertyChangedEventArgs(过去时)。
因为Split方法的这个调用将文本分成空白字符,破折号和破折号,所以您可能会认为将使用包含一些破折号和破折号的文本演示CountedLabel。 这是真的。 BaskervillesCount程序是第3章中Baskervilles程序的变体,但是这里的文本段落用CountedLabel显示,并且包含常规Label以显示单词count:

<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="BaskervillesCount.BaskervillesCountPage"Padding="5, 0"><StackLayout><toolkit:CountedLabel x:Name="countedLabel"VerticalOptions="CenterAndExpand"Text=
"Mr. Sherlock Holmes, who was usually very late in
the mornings, save upon those not infrequent
occasions when he was up all night, was seated at
the breakfast table. I stood upon the hearth-rug
and picked up the stick which our visitor had left
behind him the night before. It was a fine, thick
piece of wood, bulbous-headed, of the sort which
is known as a “Penang lawyer.” Just
under the head was a broad silver band, nearly an
inch across, “To James Mortimer, M.R.C.S.,
from his friends of the C.C.H.,” was engraved
upon it, with the date “1884.” It was
just such a stick as the old-fashioned family
practitioner used to carry—dignified, solid,
and reassuring." /><Label x:Name="wordCountLabel"Text="???"FontSize="Large"VerticalOptions="CenterAndExpand"HorizontalOptions="Center" /></StackLayout>
</ContentPage> 

常规Label在代码隐藏文件中设置:

public partial class BaskervillesCountPage : ContentPage
{public BaskervillesCountPage(){InitializeComponent();int wordCount = countedLabel.WordCount;wordCountLabel.Text = wordCount + " words";}
}

它计算的单词计数是基于这样的假设:文本中的所有连字符分开两个单词,并且“hearth-rug”和“bulbous-headed”应该被计为每个单词两个单词。 当然,这并不总是正确的,但字数不像算法那么简单,因为这个代码可能意味着:

如果文本在程序运行时动态更改,程序将如何构建? 在这种情况下,每当CountedLabel对象的WordCount属性发生更改时,都需要更新单词计数。 您可以在Count?edLabel对象上附加PropertyChanged处理程序,并检查名为“WordCount”的属性。
但是,如果您尝试从XAML设置此类事件处理程序,请务必谨慎 - 例如,如下所示:

<toolkit:CountedLabel x:Name="countedLabel"VerticalOptions="CenterAndExpand"PropertyChanged="OnCountedLabelPropertyChanged"Text=" __ " />

您可能希望在代码隐藏文件中编码事件处理程序,如下所示:

void OnCountedLabelPropertyChanged(object sender, PropertyChangedEventArgs args)
{wordCountLabel.Text = countedLabel.WordCount + " words";
}

当XAML解析器设置Text属性时,该处理程序将触发,但事件处理程序正在尝试设置尚未实例化的第二个Label的Text属性,这意味着wordCountLabel字段仍设置为null。 这是第15章在使用交互式控件时会再次出现的问题,但在第16章中处理数据绑定时,它将会得到很好的解决。
在AbsoluteLay的第14章中还有另一种可绑定属性的变体吗?out:这是附加的可绑定属性,它在实现某些类型的布局时非常有用,你将在第26章中发现, “自定义布局。”
同时,让我们看一下可绑定属性最重要的应用之一:样式。

第十一章:可绑定的基础结构(四)相关推荐

  1. 计算机网络离不开光缆,九年级物理全册 第二十一章 第四节 越来越宽的信息之路习题课件 新人教版.ppt...

    九年级物理全册 第二十一章 第四节 越来越宽的信息之路习题课件 新人教版.ppt 第二十一章信息的传递,第四节越来越宽的信息之路,1微波的性质更接近光波,大致沿_______传播,需要每隔_____k ...

  2. 自学脚手架——《热力学·统计物理》 by 汪志诚(第二,三,四,五,六,七,八,九,十,十一章)

    文章目录 第二章 均匀物质的热力学性质 2.2 麦氏关系的简单应用 - 热力学正方形(Thermodynamic square) - 外微分形式 2.6 热辐射的热力学理论 - 热辐射的基尔霍夫定律( ...

  3. 《汇编语言》王爽(第四版) 第十一章 实验11

    文章目录 前言 一.实验任务 二.实现思路 三.实现代码 四.DIY时间 1.需求分析 2.最终效果 3.实现代码 总结 前言 本文是王爽老师<汇编语言>(第四版) 第十一章 实验11 的 ...

  4. 汤晓丹的第四版计算机操作系统--第十一章总结概述

    第十一章 多媒体操作系统 媒体可分为以下六类:(1) 感觉媒体(2) 表示媒体(3) 呈现媒体(4) 存储媒体(5) 传输媒体(6) 交换媒体. 多媒体文件的特点:1.多样性,2.极高的数据率,3.实 ...

  5. Java编程思想第四版第十一章习题(下)

    这是第十一章最后一节,之后我会做前11章节的回顾(按着目录捋) 题目27-32,其中30-32因为我没有源代码,所以我贴的官网答案. 编译器:IDEA 27.写一个称为Command的类,它包含一个S ...

  6. 第四十四课第十一章Managing Tables

    第十一章Managing Tables 创建表指导原则 1.将表放置于不同的表空间 2.使用locally-managed表空间避免碎片 3.使用标准entent大小减少表空间碎片 创建临时表 1.使 ...

  7. [转]Windows Shell 编程 第十一章 【来源:http://blog.csdn.net/wangqiulin123456/article/details/7987992】...

    第十一章 探索Shell 我们现在将注意力从API转向Windows Shell本身.从这一章往后,我们的目标主要集中在清晰和全面的揭示探测器的工作原理和Shell 命名空间的构成对象上,最后给出客户 ...

  8. IT大败局----第十一章 科技虚幻的诱惑

    第十一章科技虚幻的诱惑 网络是一个科技包装的虚幻世界, 弓丨诱无数.com公司迷失在泡沫中. 虽然是虚幻世界, 但.com公司的现实同样是残酷的. 网络一一网住的到底是什么? 虚幻一一在虚幻的网络世界 ...

  9. 第十一章 多媒体应用开发(音视频播放)

    第十一章 多媒体应用开发 文章目录 第十一章 多媒体应用开发 第一节 音视频开发 1. MediaPlayer 类 1.1使用 MediaPlayer 播放音频 1.创建MediaPlayer对象,并 ...

  10. 第十一章 Direct3D Initialization

    第十一章 Direct3D Initialization 本章将完成渲染引擎的基础部分的最后一个模块Direct3D的初始化,学习Direct3D C++ API,并完成一个Direct3D应用程序. ...

最新文章

  1. 从CPU缓存看缓存的套路
  2. 地铁闸门会夹伤人吗_家长们注意啦!又有孩子被地铁闸机夹翻
  3. JavaScript事件处理程序的3种方式
  4. df 和 ll 等命令无响应处理
  5. 【论文笔记】Factorizable Graph Convolutional Networks
  6. ps-色彩饱和度的设计
  7. springboot交通事故档案管理系统答辩PPT免费下载
  8. 算法笔记(一)(教你系统学习基础算法)
  9. 不仅国产手机被撕下遮羞布,其实苹果和三星也已没了遮羞布
  10. Easypack: JEECG的容器化编译环境快速构建
  11. 读书笔记-《我的第一本算法书》
  12. 彻底卸载vm 十分有用
  13. B - Simpsons’ Hidden Talents
  14. python kil 掉子进程
  15. ajax请求 拦截窗口,ajax请求成功后新开窗口window.open()被拦截解决方法
  16. Spring WebClient 使用简介
  17. X光平板探测器(探测卡/采集卡)
  18. 10-10 常见单词 : 访问项目Gutenberg(http://gutenberg.org/ ) , 并找一些你想分析的图书。 下载这些作品的文本文件或将浏览器中的原始文本复制到文本文件中。 你可
  19. svn inport 错误
  20. 字符编码讲解:ASCII、GB2312、GBK、Unicode、UTF-8关系

热门文章

  1. 【python】matplotlib生成散点矩阵图
  2. php5.4 的 php-fpm 的重启
  3. 让谷歌、百度最快最多地收录您的网站
  4. 线程通信之多个线程循环执行,(A线程执行5次,B线程执行10次,C线程执行15次)...
  5. 使用JMeter如何实现上传文件
  6. java socket 实现 http_Java Socket编程 - 基于Socket实现HTTP下载客户端
  7. hiveserver2启动不起来_汽车一键启动除了点火,还有这些功能!车主:现在才明白...
  8. gt designer2不能初始化字体管理器_Windows Terminal 1.1预览版发布:新增字体粗细、随开机启动等功能...
  9. scatterpie | ggplot2的几何图形拓展包(1):如何在地图中添加饼图
  10. tenda 服务器无法打开网页,Win7系统网页打不开qq能上怎么办? | 192路由网