使用x:Bind擴展標記進行數據綁定,是在編譯階段完成,至於說性能優化方面,大概主要是優化CPU資源的使用,因為免去了運行階段進行綁定的過程。當然,使用這個標記僅僅是綁定上的優化,並不包括數據源。數據源的合理提取就得看開發者的策略了,如果你要提取很大批量的數據放到內存中,那么,你是免不了要消耗大量內存的。這個事情,得看實際情況而定了,任何的優化都不是絕對的,個別情況下,不優化反而會更好。
x:Bind在界面綁定不經常變更的情況下用(數據一旦顯示到界面,就不再改動),會好一些。如果數據更新頻繁,估計Bind和Binding的效果差不多。
在使用x:Bind標記時,可以結合使用x:Phase標記,該標記指定一個整數值,該值是從0開始的,如0、1、2、3等。在數據加載時會根據x:Phase的值來排序,即Phase為0的先加載,1的次之,最后加載2的。Phase的使用有點像ZIndex值。Phase值越大,就越放在后面加載,但值不一定要連續的,你可以設置成0、1、3、4、7。
為啥要弄這玩意兒呢。主要是針對某個數據源實例的某些屬性可能無法立刻返回內容的情況。比如,要加載一個山寨汽車的產品列表,可能每款汽車信息都會配上一張圖片,以方便用戶查看汽車的外觀和造型。我們知道,如果數據是從網絡上提取的話,圖片可能會加載得較慢。要是等所有對象的所有屬性都加載完成再顯示到界面上,給用戶的感覺很不好,你的應用就有可能被差評。
如果用上了x:Phase值,先把汽車型號、山寨廠商名字、配置參數等先加載,Phase設置為0;由於圖片比較慢,就將它設為Phase = 1。如此一來,數據在提取時不再等待圖片加載就直接顯示到界面上;隨后,當圖片屬性返回有效值了再慢慢把圖片顯示出來。雖然用戶看不到山寨車的圖片,但至少可以看到汽車的相關信息了。
好,說了那么多廢話,咱們還是上實例吧。
首先,我定義了一個Student類,表示一位學生信息,至於說是哪個學校的學生,你就別管了,反正不是女子學校。
public class Student { private string _name; private string _city; private int _age; private float _height; public string Name { get { return _name; } set { _name = value; } } public string City { get { Task.Delay(975).Wait(); return _city; } set { _city = value; } } public int Age { get { Task.Delay(1100).Wait(); return _age; } set { _age = value; } } public float Height { get { Task.Delay(1899).Wait(); return _height; } set { _height = value; } } }
可能有小伙伴看不懂各個屬性的get訪問器里面是啥意思,如果真是這樣,老周覺得應該拉你去批斗,說明你沒認真學.net 4.x。Task.Delay方法表示延遲N毫秒的意思,就相當於以前的Thread.Sleep方法。不過嘛,Task的Delay方法的返回類型是Task,這說明它是可以異步等待的,但是,await是用在方法中的,不用於屬性,所以為了讓代碼在這里暫停N毫秒,我還得調用一下Wait方法,這樣一來,代碼就會停在那里,等Delay完了才會繼續執行。
為什么我要在屬性的get訪問器中拖延一下時間呢,這還用說嘛,當然是為了模擬網速慢,加載慢的情況。
隨后,用XAML聲明列表控件,並設計一下它的項數據模板,以便能顯示Student類的各個屬性的值。
<ListView Name="lv" ReorderMode="Enabled"> <ListView.ItemTemplate> <DataTemplate x:DataType="local:Student"> <StackPanel> <TextBlock FontWeight="Bold" FontSize="24" Text="{x:Bind Name}" x:Phase="0"/> <TextBlock Text="{x:Bind City}" x:Phase="1"/> <TextBlock Text="{x:Bind Age}" x:Phase="2"/> <TextBlock Text="{x:Bind Height}" x:Phase="3"/> </StackPanel> </DataTemplate> </ListView.ItemTemplate> </ListView>
各個值的Phase分別是0、1、2、3,讓這幾個值產生加載的先后順序。如果不顯式設置x:Phase值,就表示它使用默認值0,即立即加載。各位要注意,如果你在DataTemplate模板中用x:Bind標記進行綁定,那么,在DataTemplate上必須用x:DataType標記指明數據源對象的類型。因為這種綁定是在編譯階段完成的,編譯必須知道數據源的確切類型,不然的話,容易造成類型安全問題。更何況,你不這樣指定,編譯器是不會讓你編譯的。
運行應用程序后,你會看到,學生姓名馬上就出來了,但其他屬性值會慢慢出現。請看下圖表演。
好了,廢話就說到這兒了,估計該知識點沒什么難度的,別告訴我你沒看懂。如果有這個示例你還不懂,那老周只好“傷心秦漢,生靈塗炭,讀書人一聲長嘆”了。
其實,老周這個示例是有超級大Bug的,但為了簡單演示,就不管那么多了。