重要的事情说三遍:

  本文基本是取自微软官方 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. C# ODP.NET 调用Oracle函数返回值时报错的一个解决方案

    有人在社区问到:C#调用Oracle中自定义函数的返回值时,无法正常调用.但在PL/SQL中正常调用返回. 于是动手一试: 1.准备函数(Oralce 11g.2.0.0.4) CREATE OR R ...

  2. TI的32位定点DSP库IQmath在H7和F4上的移植和使用

    说明: 1.最近在制作第2版DSP教程,除了ARM家的,这次重点了解下载TI的DSP库,特此移植了一个TI的IQmath. 2.初次使用这个定点库,感觉在各种Q格式的互转,Q格式数值和浮点数的互转处理 ...

  3. .net core 2.1 Nlog.Web.AspNetCore Nlog日志

    1.先创建 .net core Web 应用程序,选择API 2.安装 Nuget 包:Nlog.Web.AspNetCore install-package Nlog install-package ...

  4. 更改Dynamics 365 Customer Engagement本地部署的高级配置

    我是微软Dynamics 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面 ...

  5. 从0系统学Android--3.6 RecyclerView

    从0系统学Android--更强大的滚动控件---RecyclerView 本系列文章目录:更多精品文章分类 本系列持续更新中.... 参考<第一行代码> 首先说明一点昨天发了一篇关于 L ...

  6. C编程小结1

    1. ‘\0’表示字符串结束符 2. 变量之间互相赋值一定要考虑他们的数据类型,要强制转换匹配上了或者进行一些处理才能赋值,同时读程序的时候也要注意这一点,否则可能看不懂.如: sData[0]=wD ...

  7. kubernetes搭建(可访问外网环境部署)

    版权声明:本文为博主原创文章,支持原创,转载请附上原文出处链接和本声明. 本文链接地址:https://www.cnblogs.com/wannengachao/p/11947621.html 一.前 ...

  8. 初学Elasticsearch

    首先启动elasticsearch.bat,然后安装node.js为了支持elasticsearch-head-master插件,之后在在该插件的目录打开命令行窗口,输入grunt server即可S ...

  9. 发布Cocos2d-x的PC端程序

    发布Cocos2d-x的PC端程序 一.创建一个Release的项目 1.利用根目录下的解决方案生成Release.win32文件夹 2.新建一个cocos2d项目(比如解决方案名称MySolutio ...

  10. 10-Node.js学习笔记-异步函数

    异步函数 异步函数是异步编程语法的终极解决方案,它可以让我们将异步代码写成同步的形式,让代码不再有回调函数嵌套,是代码变得清晰明了 const fn = async()=>{} async fu ...