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閱讀 230,791評論 6 545
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,795評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,943評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,057評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,773評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,106評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,082評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,282評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,793評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,507評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,741評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,220評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,929評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,325評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,661評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,482評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,702評論 2 380

推薦閱讀更多精彩內容