[譯文] 在 Xamarin.Forms 中使用 Compiled Bindings 加速效能!

此篇文章是初次嘗試翻譯原文,其內容大多為翻譯原文所作的介紹,若有翻譯不周的情況請多多包涵!

原文出處:
https://devblogs.microsoft.com/xamarin/compiled-bindings-xamarin-forms



在 Xamarin.Forms 開發中 Data Binding 技巧是極為重要的一環。這技巧讓 Xamairn.Forms 的開發人員,能夠便捷的讓 UI 跟 C# 之間的資料互動,並自動的更新 UI 內容。可是此開發的便捷性也帶來了些狀況,由於這樣在 Xamairn.Forms 需要於執行時期分析資料以利繫結處理,就又產生了效能的影響。但現在可以透過 Compiled Bindings 的處理,來大幅地降低其效能的影響!


什麼是 Compiled Bindings ?

Compiled Binding 是讓 Xamarin.Forms 能對 Binding 的資料,在編譯時期就具型化資料以利使用。

這也就意味著 Xamairn.Forms 就不用在執行時期 (runtime) ,才進行重新解譯 Data Binding 的過程。透過使用定義在任一種 "Visual Element" 中的 XAML 延伸標記 "x:DataType" 來指定資料應具型化的類別,就能輕鬆的享受 Compiled Bindings 帶來的效益。 

 

效益

使用 Compiled Bindings 對開發的 App 帶來兩個最主要的好處:

  1. 編譯時期就檢驗 Binding 的陳述式。
  2. 透過在編譯時期處理 Binding 過程進而達到效能的提升。

 

啟用 XAML Compilation

而要使用 Compiled Binding 有個前提,就是要先啟用 XAML Compilation。

這對近期新開發 Xamarin.Forms App 的開發人員來說,這項功能應該都是預設啟用的,並且應該已經透過此 XAML Compilation 獲得效能的大幅改善。

若是要手動啟用此功能,可透過在你的共用程式碼專案加入 assembly 層的相關旗標:

[assembly:XamlCompilation(XamlCompilationOptions.Compile)]



使用 Compiled Binding

接下來就透過一段 Sample Code 來解釋,我們要做一個利用 ListView 來呈現很多猴子的資料頁面。

首先,我們有個猴子的類別 (Class) Monkey 並利用這個類別產生了多隻的猴子,形成一個集合。並設計此集合成為 MonkeysViewModel 當中的一個屬性,使其繫結到其 ListView 列表中。

而 MonkeysPage 則是我們所謂的 XAML UI 頁面。

下面則是上述文句的展示 XAML 標記:

<ContentPage 
        xmlns="http://xamarin.com/schemas/2014/forms" 
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
        x:Class="Monkeys.Views.MonkeysPage"
        Title="Monkeys">
<StackLayout>
    <Label Margin="10,0" Text="{Binding MonkeyCount, StringFormat='{0} Monkeys'}"/>
    <ListView ItemsSource="{Binding Monkeys}"
            HasUnevenRows="true">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <Grid Padding="10" RowSpacing="10" ColumnSpacing="10">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <controls:CircleImage 
                                BorderColor="Aqua"
                                BorderThickness="3"
                                HeightRequest="66"
                                WidthRequest="66"
                                HorizontalOptions="CenterAndExpand"
                                VerticalOptions="CenterAndExpand"
                                Aspect="AspectFill"
                                Source="{Binding Image}"/>
                        <StackLayout VerticalOptions="Center">
                            <Label Text="{Binding Name}"/>
                            <Label Text="{Binding Location}"/>
                        </StackLayout>
                    </Grid>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage>

這裡要注意我們透過在 MonkeysViewModel 中設計 MonkeyCount 與 Monkeys 這兩個屬性來用以繫結資料,並且針對 ListView 要呈現猴子資料們的 UI 項目中,設計了 Image, Name, 與 Location 的 UI 到其 ListView 的 DataTemplate 中的 ItemTemplate 當中。


為了使這 MonkeysViewModel 後續都能正常使用,我們必須在此頁面的 XAML 標記中增加其所需引用的 XAML 命名空間 (namespace),並且替此命名空間 (namespace) 取了別名為 "viewmodels":

xmlns:viewmodels="clr-namespace:Monkeys.ViewModels"


然後在 ContentPage 的標記節點中,我們增加了 "x:DataType" 的屬性設定:

<ContentPage 
        xmlns="http://xamarin.com/schemas/2014/forms" 
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
        x:Class="Monkeys.Views.MonkeysPage"
        xmlns:viewmodels="clr-namespace:Monkeys.ViewModels"
        x:DataType="viewmodels:MonkeysViewModel"
        Title="Monkeys">
</ContentPage>

就這樣,好戲開始啦~
 

當如果我們在 Visual Studio 中編輯 XAML 時,若不小心有 Binding 資料上的撰寫錯誤,就會 "等燈" 的得到紅色的 Compiler Error:

Compiler Error

而如果在使用類似 ListView 的這些集合元件時,有客製化其 DataTemplate 就也必須要在其身上設定 Compiled Binding 的 x:DataType,如我們的範例當中的 ListView 有個繫結集合 "ObservableCollection<Monkey>",我們就得再次如前述所作的設定,在 ListView 的 DataTemplate 當中做相關的處理。


加入 Monkey 類別的 namespace:

xmlns:models="clr-namespace:Monkeys.Models"

然後在 ListView 的 DataTemplate 當中就要設定 x:DataType 如下:

<ListView ItemsSource="{Binding Monkeys}"
          HasUnevenRows="true">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="models:Monkey">
            <ViewCell>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

就這樣,完成了喔~~~

其實跟原本的 XAML UI 的設計的時候比較起來,說實在的真沒增加多少功夫呢!


了解更多

好啦,其實在使用 Compiled Bindings 還有更多手法可以運用到你的 Xamarin.Forms App 當中。

你可以參考微軟文件 "comprehensive documentation" 了解到更多好用的方式,阿...如果你想要這個範例程式檔,那就請到這個 Blog 專屬 GitHub 找到它吧!
 


PS: 啟用 XAML Pre-compilation 會有的特殊現象,可參考 .NET 海角點部落 - Xamarin 的 XamlCompilation Attribute 後半段敘述。


 


I'm a Microsoft MVP - Developer Technologies (From 2015 ~).
 

MVP_Logo



I focus on the following topics: Xamarin Technology, Azure, Mobile DevOps, and Microsoft EM+S.

If you want to know more about them, welcome to my website:
https://jamestsai.tw 


本部落格文章之圖片相關後製處理皆透過 Techsmith 公司 所贊助其授權使用之 "Snagit" 與 "Snagit Editor" 軟體製作。