重要的事情说三遍:

  本文基本是取自微软官方 Bindable Properties, 官方也提供了机翻的中文版本,笔者只是尝试用自己的理解描述一遍,便于记忆。如有不对之处,欢迎拍砖。

  本文基本是取自微软官方 Bindable Properties, 官方也提供了机翻的中文版本,笔者只是尝试用自己的理解描述一遍,便于记忆。如有不对之处,欢迎拍砖。

  本文基本是取自微软官方 Bindable Properties, 官方也提供了机翻的中文版本,笔者只是尝试用自己的理解描述一遍,便于记忆。如有不对之处,欢迎拍砖。

概述

  首先来说说Bindableproperty是什么?官方的说是:在Xamarin.Forms中,公共语言运行时(CLR)的属性(properites)的功能由bindable properties来扩展。它是一种特殊的属性,特殊的点在于它的值是被Xamarin.Foms的属性系统跟踪的。

  它是通过使用备份一个BindableProperty的类型来实现扩展property的功能的,而不是使用备份field的方式。它的目标是提供这样一个属性系统,这个系统支持类似于父子关系的方式来设置数据绑定,样式更改等等。此外,它还额外提供了一些别的功能,如设置默认值,验证属性合法性,提供属性更改时的回调函数等等。

  上面两段内容确实很绕,换成笔者的理解是:利用BindableProperty来创建的属性不同于我们平常所使用的形如 public string abc { get; set; } 这样的普通属性,它额外提供了对数据绑定,以及相关方法的支持。这种功能是通过Xamrin.Forms这个框架自身对bindable properties的值的追踪来实现的。

  如果你有下面的某些功能的需求,那么你就应该使用bindable properties

  • 作为数据绑定的有效目标值。(注意这里是目标值(target),而不是源(source))
  • 通过样式来设置属性
  • 提供一个与该属性本身默认值不同的默认值。(如int的默认值是0,如果你想默认指定为别的值,可以使用bindable properties。原文是 Providing a default property value that's different from the default for the type of the property.
  • 验证属性的值
  • 监控这个属性值的变更

  举个例子,Xamarin.Forms自带的如 Label.Text,Button.BorderRadius,StackLayout.Orientation等等都是可绑定属性。任何一个可绑定的属性在其所在的class内都有一个由pubilc static readonly property修饰的BindableProperty对应。加粗的这句话不是很好理解,举个例子。如前面提到的Xamarin.Forms自带的Lable.Text是一个可绑定属性,那么在Lable这个类中也一定包含这样的定义

public static readonly Xamarin.Forms.BindableProperty TextProperty;

创建和实用可绑定属性

  可以使用如下的流程来创建可绑定属性:

  1. 利用 BindableProperty.Create方法来创建一个BindableProperty的实例。(该方法包括多个重载)。
  2. 为第一步骤中创建的实例定义一个属性访问器。

  请注意,所有的可绑定属性都必须在UI Thread上创建。这意味着只有跑在UI Thread上的代码可以获取(get)或改变(set)可绑定属性的值。然而,可以通过使用Device.BeginInvokeOnMainThread方法将可绑定属性的实例封送到UI Thread,来实现从其他线程访问。(这句的翻译不是很准确,原文是:However, BindableProperty instances can be accessed from other threads by marshaling to the UI thread with the Device.BeginInvokeOnMainThread method.)

  创建

  包含BindableProperty属性的类必须派生自BindableObject,但BindableObject继承关系中处于较高的位置,因此大部分用于UI的类都支持可绑定属性。

  通过使用public static readonly来声明一个可绑定属性,使用BindableProperty.Create的某个重载来创建它。此处要注意可绑定属性应该定义在BindableObject派生类的主体内,并且在该类任何成员的外部。

  创建可绑定属性时至少应该指定下面所需的参数:

  • 可绑定属性的name
  • 该属性的类型(The type of the property)
  • 包含整个属性的类的类型(The type of the owning object)
  • 默认值。这个默认值可设置为属性本身的默认值不同,如创建一个int类型的可绑定属性可将这里的默认值设置为5,而不是使用int自身的默认值0。此外,当调用ClearValue方法时也将会把值重置为我们定义的默认值。

  例如:

public static readonly BindableProperty EventNameProperty =
BindableProperty.Create ("EventName", typeof(string), typeof(EventToCommandBehavior), null);

  这段代码将创建一个名为“EventName”,string类型的可绑定属性的实例。它属于EventToCommandBehavior这个类,并且默认值是null。可绑定属性的命名规范要求其必须与Create方法中所指定的name相匹配,并在后面追加"Property"。如上面的代码,EventName与EventNameProperty。

  此外,在创建BindableProperty的实例时,还可以指定以下的一些参数

  • 绑定模式,这里不用多说了,就是绑定中所对应的那几种模式。这里的默认值是source to target。
  • 设置属性时所使用的验证方法的委托。
  • 属性更改完成时所调用方法的委托。
  • 属性更改将要发生时所调用的方法的委托,此方法与更改完成时的方法具有相同的签名。
  • 属性更改时调用的“强制值”委托。(A coerce value delegate that will be invoked when the property value has changed.)
  • 用于初始化默认属性值的Func委托。

  创建属性访问器

  需要使用属性语法(property syntax)来创建可用于访问 可绑定属性 的属性访问器。Get方法需要利用GetValue从对应的BindableProperty中获取值,再使用类型转换拿到所需的值。Set方法需要使用SetValue方法来为其复制。例如

public string EventName {
get { return (string)GetValue (EventNameProperty); }
set { SetValue (EventNameProperty, value); }
}

  使用可绑定属性

  一旦声明了可绑定属性就可以在XAML和C#代码中使用它。在XAML中,还需要先声明带有前缀的命名空间,这个空间中包含着我们创建的可绑定属性所属的类。在XAML中

  声明

<ContentPage ... xmlns:local="clr-namespace:EventToCommandBehavior" ...>
...
</ContentPage>

  使用

<ListView ...>
<ListView.Behaviors>
<local:EventToCommandBehavior EventName="ItemSelected" ... />
</ListView.Behaviors>
</ListView>

  等效的C#代码

var listView = new ListView ();
listView.Behaviors.Add (new EventToCommandBehavior {
EventName = "ItemSelected",
...
});

进阶使用场景

  检测属性更改

  在利用BindableProperety.Create方法创建可绑定属性的实例时可以通过propertyChanged参数来注册一个静态的回调方法,该方法会在可绑定属性的值发生变更时执行。例如:

public static readonly BindableProperty EventNameProperty =
BindableProperty.Create (
"EventName", typeof(string), typeof(EventToCommandBehavior), null, propertyChanged: OnEventNameChanged);
... static void OnEventNameChanged (BindableObject bindable, object oldValue, object newValue)
{
// Property changed implementation goes here
}

  OnEventNameChanged方法中的参数BindableObject bindable用于指定是哪个实例在执行这个方法,后面两个参数就不解释了。

  用于验证属性的回调函数

  注册方法与上面类似,直接贴代码

public static readonly BindableProperty AngleProperty =
BindableProperty.Create ("Angle", typeof(double), typeof(HomePage), 0.0, validateValue: IsValidValue);
... static bool IsValidValue (BindableObject view, object value)
{
double result;
bool isDouble = double.TryParse (value.ToString (), out result);
return (result >= && result <= );
}

  验证属性的这个方法会根据接收到的参数的值以及你定义好的逻辑来判断它是否通过验证。如果没有通过验证则返回false,开发需要处理这种情况。(如ui上style的变更,以提示用户输入值不满足要求等等)。如上面代码中的例子,被验证的值只有在处于[0,360]才能验证通过。

  强制值回调(Coerce Value Callback)

  注册方法与上面类似,直接贴代码

public static readonly BindableProperty AngleProperty = BindableProperty.Create (
"Angle", typeof(double), typeof(HomePage), 0.0, coerceValue: CoerceAngle);
public static readonly BindableProperty MaximumAngleProperty = BindableProperty.Create (
"MaximumAngle", typeof(double), typeof(HomePage), 360.0);
... static object CoerceAngle (BindableObject bindable, object value)
{
var homePage = bindable as HomePage;
double input = (double)value; if (input > homePage.MaximumAngle) {
input = homePage.MaximumAngle;
} return input;
}

  这里需要说明一下。coerceValue方法会在属性值发生变更时调用。它用于在属性值变更时重新改变属性的值。如上面的代码所示,可以使用它来确保一个可绑定属性的值不大于另一个可绑定属性的值。该CoerceAngle方法检查MaximumAngle属性的值,如果Angle属性值大于它,则它会将值强制转换为MaximumAngle属性值。

  使用Func创建默认值

  贴代码

public static readonly BindableProperty SizeProperty =
BindableProperty.Create ("Size", typeof(double), typeof(HomePage), 0.0,
defaultValueCreator: bindable => Device.GetNamedSize (NamedSize.Large, (Label)bindable));

  此处使用一个Device.GetNamedSize方法来获取在原生平台(native platform)上lable的字体大小,并将其设置为SizeProperty的默认值。

Xamarin Bindableproperty 可绑定属性的更多相关文章

  1. Compounding绑定属性

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  2. class中限定绑定属性__slots__方法

    使用__slots__但是,如果我们想要限制class的属性怎么办?比如,只允许对Student实例添加name和age属性.为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的 ...

  3. 绑定属性 - v-bind

    未绑定 <!DOCTYPE html><html><head>    <meta charset="utf-8">    <t ...

  4. Vue 目录结构 绑定数据 绑定属性 循环渲染数据

    一.目录结构分析 node_modules 项目所需要的各种依赖 src 开发用的资源 assets 静态资源文件 App.vue 根组件 main.js 配置路由时会用 .babelrc 配置文件 ...

  5. v-bind绑定属性样式——class的三种绑定方式

    1.布尔值的绑定方式 <div id="demo"> <span v-bind:class="{‘class-a‘:isA ,‘class-b‘:isB ...

  6. React对比Vue(02 绑定属性,图片引入,数组循环等对比)

    import React, { Component } from 'react'; import girl from '../assets/images/1.jpg' //这个是全局的不要this.s ...

  7. Angular4.x 创建组件|绑定数据|绑定属性|数据循环|条件判断|事件|表单处理|双向数据绑定

    Angular4.x 创建组件|绑定数据|绑定属性|数据循环|条件判断|事件|表单处理|双向数据绑定 创建 angular 组件 https://github.com/angular/angular- ...

  8. vue 绑定属性 绑定Class 绑定style

    <template> <div id="app"> <h2>{{msg}}</h2> <br> <div v-bi ...

  9. WPF绑定时要绑定属性,不要绑定字段

    如题(就是加get;set;),绑定属性不出东西,不知道为什么...

随机推荐

  1. 携程PMO--扑克派对,我的估算我做主!

    转自本人运营的公众号“ 携程技术中心PMO”(ID:cso_pmo)     作者简介   Ollie Guan,携程PMO高级项目集经理,负责敏捷总动员及携程技术中心PMO微信公众号运营.上海AUG ...

  2. Linux 使用grep过滤多个条件及grep常用过滤命令

    这篇文章主要介绍了Linux 使用grep筛选多个条件及grep常用过滤命令,需要的朋友可以参考下 cat log.txt | grep 条件: cat log.txt | grep 条件一 | gr ...

  3. 大数据理论篇 - 通俗易懂,揭秘谷歌《The Dataflow Model》的核心思想(一)

    目录 前言 目标 核心的设计原则 通用的数据处理流程 切合实际的解决方案 总结 延伸阅读 最后 作者:justmine 头条号:大数据达摩院 创作不易,未经授权,禁止转载,否则保留追究法律责任的权利. ...

  4. LeetCode 按序打印

    第1114题 我们提供了一个类: public class Foo {   public void one() { print("one"); }   public void tw ...

  5. bootstrap-table 常用总结-树形结构

    关于树形结构,上篇文章如果还是不能理解的话,请看这一篇.把其他的没有用到的功能都去掉,只留最基础的树形结构! 废话不多说,直接上代码!所有的数据都是走的本地,如果大家想改的话可以自己改,但是需要注意的 ...

  6. angular cli + primeNG

    目录: 1.安装  angular cli 2.创建项目 3.构建路由 4.新建组件 5.组件之间的通信 6.引入primeNG 7.修改primeNG组件样式 8.问题 -------------- ...

  7. java web轻量级开发面试教程

    最近面试java后端开发的感受:如果就以平时项目经验来面试,通过估计很难——再论面试前的准备 在上周,我密集面试了若干位Java后端的候选人,工作经验在3到5年间.我的标准其实不复杂:第一能干活,第二 ...

  8. python判断文件的访问权限

    os.access(file, mode)判断文件的访问权限file为文件mode为操作模式,有这么几种:os.F_OK: 检查文件是否存在;os.R_OK: 检查文件是否可读;os.W_OK: 检查 ...

  9. 升级python2.7至python3.7

    最近在centos7下执行命令时,出现以下提示: DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020 ...

  10. mysql操作进阶

    # ### part1 单表查询# sql 查询语句的完整语法 ''' select .. from .. where .. group by .. having .. order by .. lim ...