什麼是系結宣告? (WPF .NET)
一般而言,開發人員會直接在想要繫結資料的 UI 元素 XAML 標記中宣告繫結。 不過,您也可以在程式碼中宣告繫結。 本文說明如何在 XAML 和程式碼中宣告繫結。
必要條件
在閱讀本文之前,請務必先熟悉標記延伸的概念和使用方式。 如需標記延伸的詳細資訊,請參閱標記延伸和 WPF XAML。
資料繫結概念不在本文說明範圍內。 如需資料繫結概念的相關討論,請參閱資料繫結概觀。
在 XAML 中宣告繫結
Binding 是一種標記延伸。 當您使用繫結延伸宣告繫結時,該宣告是由一系列子句組成,這些子句接在 Binding
關鍵字後面,並以逗號 (,) 分隔。 繫結宣告中的子句可以按照任何順序,而且有許多可能的組合。 這些子句是 Name=Value 配對,其中 Name 是 Binding 屬性的名稱,而 Value 則是您為該屬性設定的值。
在標記中建立繫結宣告字串時,必須將這些字串附加至目標物件的特定相依性屬性。 下列範例示範如何使用繫結延伸模組來繫結 TextBox.Text 屬性,並指定 Source 和 Path 屬性。
<TextBlock Text="{Binding Source={StaticResource myDataSource}, Path=Name}"/>
前一範例使用 Person
的簡單資料物件類型。 下列程式碼片段是該物件的程式碼:
class Person
{
public string Name { get; set; }
public DateTime Birthdate { get; set; }
}
Public Class Person
Public Property Name As String
Public Property Birthdate As DateTime
End Class
您可以透過這種方式指定 Binding 類別的大部分屬性。 如需繫結延伸的詳細資訊,以及無法使用繫結延伸設定的 Binding 屬性清單,請參閱繫結標記延伸 (.NET Framework) 概觀。
如需在 XAML 中建立繫結的範例,請參閱如何建立資料繫結。
物件元素語法
物件元素語法是建立繫結宣告的另一種選擇。 在大部分的情況下,使用標記延伸或物件元素語法並沒有特別的優勢。 但是,若標記延伸無法支援您的案例,例如當屬性值屬於非字串型別,而沒有型別轉換時,則必須使用物件元素語法。
上一節示範如何與 XAML 延伸模組繫結。 下列範例示範執行相同的繫結,但使用物件元素語法:
<TextBlock>
<TextBlock.Text>
<Binding Source="{StaticResource myDataSource}" Path="Name"/>
</TextBlock.Text>
</TextBlock>
如需不同詞彙的詳細資訊,請參閱 XAML 語法詳細資料 (.NET Framework)。
MultiBinding 和 PriorityBinding
MultiBinding 和 PriorityBinding 不支援 XAML 延伸語法。 因此,如果您要在 XAML 中宣告 MultiBinding 或 PriorityBinding,則必須使用物件元素語法。
在程式碼中建立繫結
指定繫結的另外一種方法是直接在程式碼中的 Binding 物件上設定屬性,然後將繫結指派給屬性。 下列範例示範如何使用程式碼建立 Binding 物件。
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// Make a new data source object
var personDetails = new Person()
{
Name = "John",
Birthdate = DateTime.Parse("2001-02-03")
};
// New binding object using the path of 'Name' for whatever source object is used
var nameBindingObject = new Binding("Name");
// Configure the binding
nameBindingObject.Mode = BindingMode.OneWay;
nameBindingObject.Source = personDetails;
nameBindingObject.Converter = NameConverter.Instance;
nameBindingObject.ConverterCulture = new CultureInfo("en-US");
// Set the binding to a target object. The TextBlock.Name property on the NameBlock UI element
BindingOperations.SetBinding(NameBlock, TextBlock.TextProperty, nameBindingObject);
}
Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)
' Make a new data source object
Dim personDetails As New Person() With {
.Name = "John",
.Birthdate = Date.Parse("2001-02-03")
}
' New binding object using the path of 'Name' for whatever source object is used
Dim nameBindingObject As New Binding("Name")
' Configure the binding
nameBindingObject.Mode = BindingMode.OneWay
nameBindingObject.Source = personDetails
nameBindingObject.Converter = NameConverter.Instance
nameBindingObject.ConverterCulture = New CultureInfo("en-US")
' Set the binding to a target object. The TextBlock.Name property on the NameBlock UI element
BindingOperations.SetBinding(NameBlock, TextBlock.TextProperty, nameBindingObject)
End Sub
上述程式碼會在繫結上設定下列:
- 資料來源物件上的屬性路徑。
- 繫結的模式。
- 在此案例中,資料來源是代表人員的簡單物件執行個體。
- 選用轉換器,處理來自資料來源物件的資料,再指派給目標屬性。
當您繫結的物件是 FrameworkElement 或 FrameworkContentElement 時,您可以直接在物件上呼叫 SetBinding
方法,而不是使用 BindingOperations.SetBinding。 如需範例,請參閱如何:使用程式碼建立繫結。
前一範例使用 Person
的簡單資料物件類型。 以下是該物件的程式碼:
class Person
{
public string Name { get; set; }
public DateTime Birthdate { get; set; }
}
Public Class Person
Public Property Name As String
Public Property Birthdate As DateTime
End Class
繫結路徑語法
使用 Path 屬性來指定您要繫結的來源值:
在最簡單的狀況中,Path 屬性值是用於繫結之來源物件的屬性名稱,例如
Path=PropertyName
。您可以使用 C# 中所用的類似語法,指定屬性的子屬性。 例如,子句
Path=ShoppingCart.Order
會將繫結設定為物件或屬性ShoppingCart
的子屬性Order
。若要繫結至附加屬性,請在附加屬性前後加上括號。 例如,若要繫結至附加屬性 DockPanel.Dock,語法為
Path=(DockPanel.Dock)
。屬性的索引子可以在方括弧內指定,接在套用索引子的屬性名稱後面。 例如,子句
Path=ShoppingCart[0]
會將繫結設定為索引,而該索引對應於屬性之內部索引處理常值字串 "0" 的方式。 此語法也支援巢狀索引子。Path
子句中可以混合使用索引子和子屬性;例如,Path=ShoppingCart.ShippingInfo[MailingAddress,Street].
索引子內部。 您可以使用多個以逗號 (
,
) 分隔的索引子參數。 各個參數的型別可以使用括號指定。 例如,您可以加入Path="[(sys:Int32)42,(sys:Int32)24]"
,其中sys
對應至System
命名空間。當來源為集合檢視時,就可以使用斜線 (
/
) 指定目前的項目。 例如,子句Path=/
會將繫結設定為檢視中目前的項目。 如果來源為集合,這個語法就會指定預設集合檢視目前的項目。屬性名稱和斜線可以組合用來周遊本身為集合的屬性。 例如,
Path=/Offices/ManagerName
會指定來源集合目前的項目,其中包含同樣為集合的Offices
屬性。 其目前項目為包含ManagerName
屬性的物件。也可以選擇使用句號 (
.
) 路徑來繫結至目前的來源。 例如,Text="{Binding}"
相當於Text="{Binding Path=.}"
。
逸出機制
在索引子 (
[ ]
) 內部,插入點字元 (^
) 會逸出下一個字元。如果您在 XAML 中設定 Path,則也必須逸出 (使用 XML 實體) XML 語言定義特有的某些字元:
使用
&
逸出 "&
" 字元。使用
>
逸出結尾標記 「>
」。
此外,如果您使用標記延伸語法在屬性中描述完整的繫結,您必須逸出 (使用反斜線
\
) WPF 標記延伸剖析器特有的字元:反斜線 (
\
) 本身是逸出字元。等號 (
=
) 會分隔屬性名稱和屬性值。逗號 (
,
) 會分隔屬性。右大括號 (
}
) 是標記延伸的結尾。
繫結方向
使用 Binding.Mode 屬性來指定繫結的方向。 以下模式是繫結更新的可用選項:
繫結模式 | 描述 |
---|---|
BindingMode.TwoWay | 每當目標屬性或來源屬性變更,即會更新目標屬性或來源屬性。 |
BindingMode.OneWay | 只有在來源屬性變更時,才會更新目標屬性。 |
BindingMode.OneTime | 只有在應用程式啟動或 DataContext 發生變更時,才會更新目標屬性。 |
BindingMode.OneWayToSource | 當目標屬性變更時,更新來源屬性。 |
BindingMode.Default | 導致使用目標屬性的預設 Mode 值。 |
如需詳細資訊,請參閱 BindingMode 列舉。
下列範例示範如何設定 Mode 屬性:
<TextBlock Name="IncomeText" Text="{Binding Path=TotalIncome, Mode=OneTime}" />
若要偵測來源變更 (適用於 OneWay 和 TwoWay 繫結),來源必須實作適當的屬性變更通知機制,例如 INotifyPropertyChanged。 如需詳細資訊,請參閱提供變更通知。
對於 TwoWay 或 OneWayToSource 繫結,您可以藉由設定 UpdateSourceTrigger 屬性來控制來源更新的時機。 如需詳細資訊,請參閱UpdateSourceTrigger。
預設行為
如果宣告中未指定,則預設行為如下:
建立預設轉換器,以嘗試在繫結來源值和繫結目標值之間執行型別轉換。 如果無法進行轉換,預設轉換器會傳回
null
。如果您未設定 ConverterCulture,繫結引擎會使用繫結目標物件的
Language
屬性。 在 XAML 中,這個值預設為en-US
,但如果已明確設定,則會繼承頁面的根元素 (或任何元素) 值。只要繫結已經有資料內容 (例如,繼承的資料內容來自父元素),而且該內容所傳回的任何項目或集合不需要進一步修改路徑即可適用於繫結,繫結宣告可以完全沒有子句:
{Binding}
。 這通常是資料樣式設定指定繫結的方式,其中繫結的作用對象是集合。 如需詳細資訊,請參閱使用整個物件做為繫結來源。根據所繫結的相依性屬性,預設 Mode 在單向和雙向之間有所不同。 您永遠都可以明確宣告繫結模式,以確保繫結具有所需的行為。 一般而言,使用者可以編輯的控制項屬性,例如 TextBox.Text 和 RangeBase.Value,預設為雙向繫結,但其他大多數屬性則預設為單向繫結。
根據繫結相依性屬性,PropertyChanged 與 LostFocus 之間的預設 UpdateSourceTrigger 值也會不同。 大多數相依性屬性的預設值為 PropertyChanged,而 TextBox.Text 屬性具有 LostFocus 的預設值。