重要的事情说三遍:

  本文基本是取自微软官方 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. Unity Ruby's Adventure 第一步

    官方游戏教程:https://learn.unity.com/project/ruby-s-2d-rpg?language=en 鲁比大冒险是一个2D游戏入门教程,涉及动画,特效,UI,瓦片地图,音效 ...

  2. Hystrix集群及集群监控turbine

    Hystrix集群及监控turbine 前面Dashboard演示的仅仅是单机服务监控,实际项目基本都是集群,所以这里集群监控用的是turbine. turbine是基于Dashboard的. 先搞个 ...

  3. Jmeter性能测试分布式技术

    一.什么是分布式测试 分布式测试是指通过局域网和Internet,把分布于不同地点.独立完成特定功能的测试计算机连接起来,以达到测试资源共享.分散操作.集中管理.协同工作.负载均衡.测试过程监控等目的 ...

  4. SQLserver还原失败(数据库正在使用,无法获得对数据库的独占访问权)

    问题描述: Sql server还原失败(数据库正在使用,无法获得对数据库的独占访问权) 数据库还原的时候还有其他进程连在上面,导致无法获得独占造成的. 这个问题的原因在于有用户连接了当前要做还原的数 ...

  5. k8s的yaml说明

    理解k8s里的几个概念 Kubernetes 通过各种 Controller 来管理 Pod 的生命周期.为了满足不同业务场景,Kubernetes 开发了 Deployment.ReplicaSet ...

  6. Maven简介与使用

    Maven介绍 Maven是项目管理工具,对软件项目提供构建与依赖管理 Mavan是Apache下的Java开源项目 Mavan为Java项目提供了统一的管理方式,已成为业界标准 Maven核心特性 ...

  7. OpenTSDB 简单使用 .NET

    OpenTSDB是基于Hbase的时序数据库[时间序列数据库].不具备通用性,主要针对具有时间特性和需求的数据,如监控数据.温度变化数据等. 1.安装OpenTSDB 安装前一定要安装HBase,相关 ...

  8. Bug 28450914 : ORA-600: [KDLRCI_GET_INLINE_DATA] SELECTING FROM CDB_FEATURE_USAGE_STATISTICS

    alert日志报错: 2019-11-18T07:15:12.704938+08:00Errors in file /u01/app/oracle/diag/rdbms/sibcyb1/SIBCYB1 ...

  9. C# Distinct去重泛型List

    List<int>去重 List<string>去重 List<T>去重 1. List<int>去重 List<int> ilist = ...

  10. MySQL数据库:group分组

    group by:分组 GroupBy语句从英文的字面意义上理解就是"根据(by)一定的规则进行分组(Group)".它的作用是通过一定的规则将一个数据集划分成若干个小的区域,然后 ...