数据绑定(Binding)
Windows Presentation Foundation (WPF) 中的數(shù)據(jù)綁定為應(yīng)用程序提供了一種簡單、一致的數(shù)據(jù)表示和交互方法。元素能夠以公共語言運(yùn)行時(shí) (CLR) 對象和 XML 形式綁定到來自各種數(shù)據(jù)源的數(shù)據(jù)。
什么是數(shù)據(jù)綁定?
數(shù)據(jù)綁定是在應(yīng)用程序 UI 與業(yè)務(wù)邏輯之間建立連接的過程。如果綁定具有正確設(shè)置并且數(shù)據(jù)提供正確通知,則當(dāng)數(shù)據(jù)更改其值時(shí),綁定到數(shù)據(jù)的元素會(huì)自動(dòng)反映更改。數(shù)據(jù)綁定可能還意味著如果元素中數(shù)據(jù)的外部表現(xiàn)形式發(fā)生更改,則基礎(chǔ)數(shù)據(jù)可以自動(dòng)更新以反映更改。例如,如果用戶編輯 TextBox 元素中的值,則基礎(chǔ)數(shù)據(jù)值會(huì)自動(dòng)更新以反映該更改。
基本數(shù)據(jù)綁定概念
不論要綁定什么元素,不論數(shù)據(jù)源的特性是什么,每個(gè)綁定都始終遵循下圖所示的模型:
如上圖所示,數(shù)據(jù)綁定實(shí)質(zhì)上是綁定目標(biāo)與綁定源之間的橋梁。該圖演示以下基本的 WPF 數(shù)據(jù)綁定概念:
- 通常,每個(gè)綁定都具有四個(gè)組件:綁定目標(biāo)對象、目標(biāo)屬性、綁定源,以及要使用的綁定源中的值的路徑。例如,如果要將 TextBox 的內(nèi)容綁定到 Employee 對象的 Name 屬性,則目標(biāo)對象是 TextBox,目標(biāo)屬性是 Text 屬性,要使用的值是 Name,源對象是 Employee 對象。
- 目標(biāo)屬性必須為依賴項(xiàng)屬性。大多數(shù) UIElement 屬性都是依賴項(xiàng)屬性,而大多數(shù)依賴項(xiàng)屬性(除了只讀屬性)默認(rèn)情況下都支持?jǐn)?shù)據(jù)綁定。(只有DependencyObject 類型可以定義依賴項(xiàng)屬性,所有 UIElement 都派生自 DependencyObject。)
- 盡管圖中并未指出,但應(yīng)該注意,綁定源對象并不限于自定義 CLR 對象。WPF 數(shù)據(jù)綁定支持 CLR 對象和 XML 形式的數(shù)據(jù)。舉例來說,綁定源可以是 UIElement、任何列表對象、與 ADO.NET 數(shù)據(jù)或 Web 服務(wù)關(guān)聯(lián)的 CLR 對象,或是包含 XML 數(shù)據(jù)的 XmlNode。有關(guān)更多信息,請參見綁定源概述
特別注意:當(dāng)建立綁定時(shí),是將綁定目標(biāo)綁定到 綁定源。例如,如果要使用數(shù)據(jù)綁定在一個(gè) ListBox 中顯示一些基礎(chǔ) XML 數(shù)據(jù),就是將 ListBox 綁定到 XML 數(shù)據(jù)。
數(shù)據(jù)流的方向
正如上文所述和上圖中箭頭所示,綁定的數(shù)據(jù)流可以從數(shù)據(jù)目標(biāo)流向數(shù)據(jù)源(例如,當(dāng)用戶編輯 TextBox 的值時(shí),源值會(huì)發(fā)生更改)和/或(如果綁定源提供正確的通知)從綁定源流向綁定目標(biāo)(例如,TextBox 內(nèi)容會(huì)隨綁定源中的更改而進(jìn)行更新)。
有時(shí)可能希望應(yīng)用程序使用戶可以更改數(shù)據(jù)并將數(shù)據(jù)傳播回源對象。或者,可能不希望允許用戶更新源數(shù)據(jù)。可以通過設(shè)置 Binding 對象的 Mode 屬性來對此進(jìn)行控制。下圖演示不同類型的數(shù)據(jù)流:
- OneWay 綁定導(dǎo)致對源屬性的更改會(huì)自動(dòng)更新目標(biāo)屬性,但是對目標(biāo)屬性的更改不會(huì)傳播回源屬性。此綁定類型適用于綁定的控件為隱式只讀控件的情況。例如,可能綁定到如股票行情自動(dòng)收錄器這樣的源,或許目標(biāo)屬性沒有用于進(jìn)行更改的控件接口(如表的數(shù)據(jù)綁定背景色)。如果無需監(jiān)視目標(biāo)屬性的更改,則使用 OneWay 綁定模式可避免 TwoWay 綁定模式的系統(tǒng)開銷。
- TwoWay 綁定導(dǎo)致對源屬性的更改會(huì)自動(dòng)更新目標(biāo)屬性,而對目標(biāo)屬性的更改也會(huì)自動(dòng)更新源屬性。此綁定類型適用于可編輯窗體或其他完全交互式 UI 方案。大多數(shù)屬性都默認(rèn)為 OneWay 綁定,但是一些依賴項(xiàng)屬性(通常為用戶可編輯的控件的屬性,如 TextBox 的 Text 屬性和 CheckBox 的 IsChecked 屬性)默認(rèn)為 TwoWay 綁定。確定依賴項(xiàng)屬性綁定在默認(rèn)情況下是單向還是雙向的編程方法是:使用 GetMetadata 獲取屬性的屬性元數(shù)據(jù),然后檢查 BindsTwoWayByDefault 屬性的布爾值。
- OneWayToSource 與 OneWay 綁定相反;它在目標(biāo)屬性更改時(shí)更新源屬性。一個(gè)示例方案是您只需要從 UI 重新計(jì)算源值的情況。
- OneTime 綁定未在圖中顯示,該綁定會(huì)導(dǎo)致源屬性初始化目標(biāo)屬性,但不傳播后續(xù)更改。這意味著,如果數(shù)據(jù)上下文發(fā)生了更改,或者數(shù)據(jù)上下文中的對象發(fā)生了更改,則更改會(huì)反映在目標(biāo)屬性中。如果您使用的數(shù)據(jù)的當(dāng)前狀態(tài)的快照適于使用,或者這些數(shù)據(jù)是真正靜態(tài)的,則適合使用此綁定類型。如果要使用源屬性中的某個(gè)值初始化目標(biāo)屬性,并且事先不知道數(shù)據(jù)上下文,則也可以使用此綁定類型。此綁定類型實(shí)質(zhì)上是 OneWay 綁定的簡化形式,在源值不更改的情況下可以提供更好的性能。
特別注意:若要檢測源更改(適用于 OneWay 和 TwoWay 綁定),則源必須實(shí)現(xiàn)一種合適的屬性更改通知機(jī)制(如 INotifyPropertyChanged)。有關(guān) INotifyPropertyChanged 實(shí)現(xiàn)的示例,請參見如何:實(shí)現(xiàn)屬性更改通知。
觸發(fā)源更新的原因
TwoWay 或 OneWayToSource 綁定偵聽目標(biāo)屬性的更改,并將這些更改傳播回源。這稱為更新源。例如,可以編輯文本框中的文本以更改基礎(chǔ)源值。
但是,源值是在您編輯文本的同時(shí)進(jìn)行更新,還是在您結(jié)束編輯文本并將鼠標(biāo)指針從文本框移走后才進(jìn)行更新呢?綁定的 UpdateSourceTrigger 屬性確定觸發(fā)源更新的原因。下圖中右箭頭的點(diǎn)演示 UpdateSourceTrigger 屬性的角色:
如果 UpdateSourceTrigger 值為 PropertyChanged,則 TwoWay 或 OneWayToSource 綁定的右箭頭指向的值會(huì)在目標(biāo)屬性更改時(shí)立刻進(jìn)行更新。但是,如果 UpdateSourceTrigger 值為 LostFocus,則僅當(dāng)目標(biāo)屬性失去焦點(diǎn)時(shí),該值才會(huì)使用新值進(jìn)行更新。
與 Mode 屬性類似,不同的依賴項(xiàng)屬性具有不同的默認(rèn) UpdateSourceTrigger 值。大多數(shù)依賴項(xiàng)屬性的默認(rèn)值都為 PropertyChanged,而 Text 屬性的默認(rèn)值為 LostFocus。這意味著,只要目標(biāo)屬性更改,源更新通常都會(huì)發(fā)生,這對于 CheckBox 和其他簡單控件很有用。但對于文本字段,每次鍵擊之后都進(jìn)行更新會(huì)降低性能,用戶也沒有機(jī)會(huì)在提交新值之前使用退格鍵修改鍵入錯(cuò)誤。這就是為什么 Text 屬性的默認(rèn)值是 LostFocus 而不是 PropertyChanged 的原因。
創(chuàng)建綁定
前面幾節(jié)中討論的一些概念可以概括為:使用 Binding 對象建立綁定,每個(gè)綁定通常都具有四個(gè)組件:綁定目標(biāo)、目標(biāo)屬性、綁定源、要使用的源值的路徑。本節(jié)討論如何設(shè)置綁定。
請看下面的示例,其中的綁定源對象是一個(gè)名為 MyData 的類,該類在 SDKSample 命名空間中定義。出于演示的目的,MyData 類具有一個(gè)名為 ColorName 的字符串屬性,該屬性的值設(shè)置為“Red”。因此,此示例生成一個(gè)具有紅色背景的按鈕。
C#:
<DockPanel
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:c="clr-namespace:SDKSample"><DockPanel.Resources><c:MyData x:Key="myDataSource"/></DockPanel.Resources><DockPanel.DataContext><Binding Source="{StaticResource myDataSource}"/></DockPanel.DataContext><Button Background="{Binding Path=ColorName}"Width="150" Height="30">I am bound to be RED!</Button>
</DockPanel> 如果將此示例應(yīng)用于基本關(guān)系圖,則生成的圖如下所示。這是一個(gè) OneWay 綁定,因?yàn)?Background 屬性在默認(rèn)情況下支持 OneWay 綁定。
指定綁定源
請注意,在上一個(gè)示例中,綁定源是通過設(shè)置 DockPanel 元素上的 DataContext 屬性來指定的。Button 隨后從 DockPanel(這是其父元素)繼承 DataContext 值。在這里重復(fù)一下,綁定源對象是綁定的四個(gè)必需組件之一。因此,如果未指定綁定源對象,則綁定將沒有任何作用。
可通過多種方法指定綁定源對象。在將多個(gè)屬性綁定到相同源時(shí),可以使用父元素上的 DataContext 屬性。但是,在各個(gè)綁定聲明上指定綁定源有時(shí)可能更為合適。對于上一個(gè)示例,可以不使用 DataContext 屬性,而是通過在按鈕的綁定聲明上直接設(shè)置 Source 屬性來指定綁定源,如下面的示例中所示:
<DockPanel.Resources><c:MyData x:Key="myDataSource"/>
</DockPanel.Resources>
<Button Width="150" Height="30"Background="{Binding Source={StaticResource myDataSource},Path=ColorName}">I am bound to be RED!</Button> 除了在元素上直接設(shè)置 DataContext 屬性、從上級繼承 DataContext 值(如第一個(gè)示例中的按鈕)、通過設(shè)置 Binding 上的 Source 屬性來顯式指定綁定源(如最后一個(gè)示例中的按鈕),還可以使用 ElementName 屬性或 RelativeSource 屬性指定綁定源。當(dāng)綁定到應(yīng)用程序中的其他元素時(shí)(例如在使用滑塊調(diào)整按鈕的寬度時(shí)),ElementName 屬性是很有用的。當(dāng)在 ControlTemplate 或 Style 中指定綁定時(shí),RelativeSource 屬性是很有用的。
指定值的路徑
- 如果綁定源是一個(gè)對象,則可使用 Path 屬性指定要用于綁定的值。如果要綁定到 XML 數(shù)據(jù),則可使用 XPath 屬性指定該值。在某些情況下,可以使用 Path 屬性,即使在數(shù)據(jù)為 XML 時(shí)。例如,如果要訪問返回的 XmlNode(作為 XPath 查詢的結(jié)果)的 Name 屬性,則應(yīng)使用 Path 屬性和 XPath 屬性。
- 請注意,雖然我們已強(qiáng)調(diào)要使用的值的 Path 是綁定的四個(gè)必需組件之一,但在要綁定到整個(gè)對象的情況下,要使用的值會(huì)與綁定源對象相同。在這些情況下,不指定 Path 比較合適。請看下面的示例:
C#:
<ListBox ItemsSource="{Binding}"IsSynchronizedWithCurrentItem="true"/> - 上面的示例使用空綁定語法:{Binding}。在此情況下,ListBox 從父 DockPanel 元素繼承 DataContext(此示例中未演示)。當(dāng)未指定路徑時(shí),默認(rèn)為綁定到整個(gè)對象。換句話說,在此示例中路徑已被省略,因?yàn)橐獙?ItemsSource 屬性綁定到整個(gè)對象。
- 除了綁定到集合以外,在希望綁定到整個(gè)對象,而不是僅綁定到對象的單個(gè)屬性時(shí),也可以使用此方案。例如,在源對象為類型字符串,并且您僅僅希望綁定到該字符串本身時(shí)。
參考資料:數(shù)據(jù)綁定概述 https://msdn.microsoft.com/zh-cn/library/ms752347(v=vs.90).aspx
版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。
轉(zhuǎn)載于:https://www.cnblogs.com/gongchuangsu/p/4850202.html
總結(jié)
以上是生活随笔為你收集整理的数据绑定(Binding)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: innodb force recover
- 下一篇: 乌镇适合几月份去