Xamarin.From中的Data binding(数据绑定)(一)

事件和事件处理在任何编程开发过程中都是一件特别繁琐的事情。Xamarin.From中提供的Data binding特性,可以将两个对象的属性自动关联起来,从而极大地简化事件处理的流程。此外,Data binding还是MVVM(Model-View-ViewModel)应用架构中非常核心的角色,是实现显示与数据处理分离的关键特性。本文,我就与大家一起来学习Data binding的相关知识。

基础知识

Data binding 相关的类、属性及方法:
  • Binding类,继承自BindingBase,定义了数据绑定的许多特性;
  • BindingContext属性,由BindableObject定义;
  • SetBinding方法,由BindableObject定义;
  • BindableObjectExtensions类中定义了两个SetBinding方法的重载;
支持XAML标志扩展的两个类:
  • BindingExtension类,为Xamarin.Forms私有,提供在XAML中使用Binding标识进行数据绑定的支持;
  • ReferenceExtension类,这也是数据绑定的关键类;
与Data binding相关的两个接口:
  • INotifyPropertyChanged(在System.ComponentModel命名空间下),用于在属性发生变化时发送通知的标准接口;
  • IValueConverter(在Xamarin.Forms 命名空间下),用于在数据绑定中的类型转换;

Data binding的核心思想:Data binding总是有一个源(source)和一个目标(target);源是某个对象的一个属性,通常会在运行期间发生变化;当这个属性变化时,Data binding将自动将这一变化更新到目标上,即另一个对象的一个属性上。

有一点特别重要:Data binding中的目标必须是一个BindableProperty对象;

对源则没有这样的要求,因此源可以是一个普通的C#属性;但在一般的数据绑定中,源的变化应当引起目标的变化,这种变化需要某种通知机制进行传递。这里有一个现成的机制—— INotifyPropertyChanged接口。INotifyPropertyChanged接口的内容非常简单,仅仅定义了个PropertyChanged事件,这个事件在属性变化时会被触发;

public interface INotifyPropertyChanged {
    event PropertyChangedEventHandler PropertyChanged; 
}

因此,Data binding中的源必须实现INotifyPropertyChanged接口;

而BindableObject正好就实现了INotifyPropertyChanged接口,因此,只需将源定义成BindableObject对象即可,这样它既可以成为源,也可以成为目标。而只实现INotifyPropertyChanged就只能作为源,不过,这么做也有好处,就是在实现上更简单,我们后面再介绍只使用INotifyPropertyChanged的做法。


BindableObject和BindableProperty

那么BindableObject和BindableProperty是什么关系呢?

** BindableObject提供了对BindableProperty对象的支持,而BindableProperty是对CLR属性的扩展。**

所谓的CLR属性即是我们一般情况下使用的C#属性,CLR是Common Language Runtiome通用语言运行时的缩写。

在Xamarin.Form中,大多数的View、Layout和Page都是BindableObject对象。


以最简单的Label为例,Label是一个BindableObject,其Text属性是一个可绑定的CLR属性。
我们一般是这样使用Text属性的。

Label label1 = new Label();
label1.Text = "Some Text";

但其实下面的做法是等效的:

Label label2 = new Label();
label2.SetValue(Label.TextProperty, "Some Text");

因为Text属性的本质是这样的:

public string Text
{ 
 set { SetValue(Label.TextProperty, value); }
 get { return (string)GetValue(Label.TextProperty); 
}

其中SetValue和GetValue都是BindableObject中定义的方法。Label.TextProperty则一个BindableProperty对象。

//TextProperty在Label类中的声明
public static readonly BindableProperty TextProperty;

可见,关于Text属性的所有工作都是通过SetValue和GetValue完成的。而对Text的调用本质上都是对Label.TextProperty的调用,而Label.TextProperty为Text提供了一整套进行数据绑定的机制,因此Text也就成为了可绑定的属性。

那么下面我们说一说如何定义BindableProperty对象。

假设我们要为一个类增加一个可绑定的TestProperty属性,写法大致如下:

 public class MyClass : BindableObject
      {
         public static readonly BindableProperty TestProperty 
                                                =BindableProperty.Create("Test", //属性名称 propertyName
                                                typeof(int),     //返回类型 returnType
                                                typeof(MyClass), // 声明者的类型 declaringType
                                                8, //默认值 defaultValue
                                                ...);
         ...
         public int Test //同上面的属性名称一致
         {
           set { SetValue(TestProperty, value); }
           get { return (int)GetValue(TestProperty); }
         }
         ...
}

BindableProperty.Create方法其实还有6个可选参数:


其中defaultBindingMode是默认的绑定模式;validateValue是检查值合法性的回调方法;propertyChanged和propertyChanging分别是值发生改变后和正上改变时触发的回调方法;coerceValue是在值发生改变时,可以对值进行处理的回调方法;这三个方法的发生顺序是coerceValue-》propertyChanging-》propertyChanged。而defaultValueCreator是可以根据需要提供不同默认值的回调方法,当然这个方法只发生在绑定的最开始。

其使用方法很简单,假使现在有一个TestBindingable :ContentPage,我们定义的XAML如下:

...
<StackLayout>
        <Label
            Text="Text"
            x:Name="label" />
        <Button
            Text="button_click"
            Clicked="button_click" />
    </StackLayout>
...

在C#代码文件中,

...
MyClass myClass = new MyClass();
public TestBindingable() {
    InitializeComponent();
    label.BindingContext = myClass;
    label.SetBinding(Button.FontSizeProperty, "Test");
}

void button_click(object sender, System.EventArgs e) {
    myClass.Test += 2;
}
...

运行之后,我们每点击一次button_click按钮,就会发现Label中的字体变大一点,可见Label的FontSize属性与myClass.Test绑定在了一起。

其它的,我们下一篇再继续介绍吧。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容