{x:Bind} 標記延伸
注意:有關在應用程式中透過 {x:Bind} 使用資料繫結的一般資訊 (以及 {x:Bind} 和 {Binding} 之間的全面比較),請參閱深入瞭解資料繫結。
{x:Bind} 標記延伸 — Windows 10 的新功能 — 是 {Binding} 的替代方案。 {x:Bind} 比 {Binding} 執行階段和記憶體更少,並且支援更好的偵錯。
在 XAML 編譯階段,{x:Bind} 會轉換成程式碼,以從資料來源上的屬性取得值,並在標記中指定的屬性上設定該值。 可以選擇將繫結物件設定為觀察資料來源屬性值的變化,並根據這些變化重新自整自身 (Mode="OneWay"
)。 它也可以選擇性地設定為將本身值中的變更推送回來源屬性 (Mode="TwoWay"
)。
{x:Bind} 所建立的繫結物件和 {Binding} 基本上功能相等。 但 {x:Bind} 會執行在編譯時期產生的特殊用途程式碼,而 {Binding} 則使用一般用途執行階段物件檢查。 因此,{x:Bind} 繫結 (通常稱為編譯繫結) 具有出色的性能,提供繫結運算式的編譯時驗證,並透過允許您在做為部分類別產生的程式碼檔案中設定斷點來支援偵錯。 您可以在 obj
資料夾中找到這些檔案,名稱如 (適用於 C#) <view name>.g.cs
。
提示
{x:Bind} 的預設模式為 OneTime,而 {Binding} 的預設模式為 OneWay。 這是基於效能考慮而選擇的,因為使用 OneWay 會導致產生更多程式碼來連結及處理變更偵測。 您可以明確指定使用 OneWay 或 TwoWay 繫結的模式。 您也可以使用 x:DefaultBindMode 來變更標記樹狀結構特定區段 {x:Bind} 的預設模式。 指定的模式會套用至該元素及其下層上的任何 {x:Bind} 運算式,這些運算式不會明確指定模式做為繫結的一部分。
示範 {x:Bind} 的範例應用程式
- {x:Bind} 範例
- QuizGame \(英文\)
- XAML 控制項庫
XAML 屬性用法
<object property="{x:Bind}" .../>
-or-
<object property="{x:Bind propertyPath}" .../>
-or-
<object property="{x:Bind bindingProperties}" .../>
-or-
<object property="{x:Bind propertyPath, bindingProperties}" .../>
-or-
<object property="{x:Bind pathToFunction.functionName(functionParameter1, functionParameter2, ...), bindingProperties}" .../>
詞彙 | 描述 |
---|---|
propertyPath | 指定繫結之屬性路徑的字串。 詳細資訊位於下方的 [屬性路徑] 區段中。 |
bindingProperties | |
propName=value[, propName=value]* | 使用名稱/值配對語法指定的一或多個繫結屬性。 |
propName | 將在繫結物件上設定的屬性的字串名稱。 例如,「轉換器」。 |
value | 將屬性設定為的值。 引數的語法取決於所設定的屬性。 下面是 propName=value 用法的範例,其中值本身就是標記延伸:Converter={StaticResource myConverterClass} 。 有關詳細資訊,請參閱以下可以使用 {x:Bind} 設定的屬性部分。 |
範例
<Page x:Class="QuizGame.View.HostView" ... >
<Button Content="{x:Bind Path=ViewModel.NextButtonText, Mode=OneWay}" ... />
</Page>
此範例 XAML 使用具有 ListView.ItemTemplate 屬性的 {x:Bind}。 請注意 x:DataType 值的宣告。
<DataTemplate x:Key="SimpleItemTemplate" x:DataType="data:SampleDataGroup">
<StackPanel Orientation="Vertical" Height="50">
<TextBlock Text="{x:Bind Title}"/>
<TextBlock Text="{x:Bind Description}"/>
</StackPanel>
</DataTemplate>
屬性路徑
PropertyPath 會設定 {x:Bind} 運算式的路徑。 Path 是屬性路徑,指定您要繫結至之屬性、子屬性、欄位或方法的值 (來源)。 您可以明確提及 Path 屬性的名稱:{x:Bind Path=...}
。 或者,您可以省略它:{x:Bind ...}
。
屬性路徑解析
{x:Bind} 不會使用 DataContext 做為預設來源,而是使用頁面或使用者控制項本身。 因此,它會在頁面的程式碼後置或使用者控制項中查看屬性、欄位和方法。 若要將檢視模型公開至 {x:Bind},您通常會想要將新的欄位或屬性新增至頁面或使用者控制項的程式碼後置。 屬性路徑中的步驟會以點 (.) 分隔,而且您可以包含多個分隔符號來周遊後續的子屬性。 不論用來實作繫結的物件的程式設計語言為何,都使用點分隔符號。
例如:在頁面中,Text="{x:Bind Employee.FirstName}" 會在頁面上尋找 Employee 成員,然後在 Employee 傳回的物件上尋找 FirstName 成員。 如果您要將項目控制項繫結至包含員工相依項目的屬性,則屬性路徑可能是「Employee.Dependents」,而項目控制項的項目範本會負責在「相依項目」中顯示項目。
針對 C++/CX,{x:Bind} 無法繫結至頁面或資料模型中的私人欄位和屬性,您必須有公用屬性才能繫結。 繫結介面區必須公開為 CX 類別/介面,以便我們可以取得相關的中繼資料。 應該不需要 [Bindable] 屬性。
使用 x:Bind 時,您不需要使用 ElementName=xxx 做為繫結運算式的一部分。 相反地,您可以使用元素的名稱做為繫結路徑的第一個部分,因為具名元素會成為代表根繫結來源之頁面或使用者控制項內的欄位。
集合
如果資料來源是集合,則屬性路徑可以依集合中的位置或索引來指定集合中的項目。 例如,「Teams[0].Players」,其中文字「[]」包含請求零索引集合中第一個項目的「0」。
若要使用索引子,模型需要對要索引的屬性的類型實作 IList<T> 或 IVector<T>。 (注意:IReadOnlyList<T> 和 IVectorView<T> 不支援索引子語法。如果索引屬性的類型支援 INotifyCollectionChanged 或 IObservableVector,且繫結為 OneWay 或 TwoWay,則會在這些介面上註冊並接聽變更通知。 變更偵測邏輯會根據所有集合變更進行更新,即使這不會影響特定的索引值也一樣。 這是因為接聽邏輯在集合的所有執行個體中很常見。
如果資料來源是 Dictionary 或 Map,則屬性路徑可以依字串名稱指定集合中的項目。 例如,<TextBlock Text="{x:Bind Players['John Smith']}" /> 將在字典中尋找名為「John Smith」的項目。 名稱必須以引號括住,而且可以使用單引號或雙引號。 揚抑符 (^) 可以用來逸出字串中的引號。 通常最簡單的方式是使用 XAML 屬性所使用的替代引號。 (請注意,IReadOnlyDictionary<T> 和 IMapView<T> 不支援索引子語法。)
若要使用字串索引器,模型必須在要編制索引的屬性類型上實作 IDictionary<字串 T> 或 IMap< 字串。> 如果索引屬性的類型支援 IObservableMap,且繫結為 OneWay 或 TwoWay,則會在這些介面上註冊並接聽變更通知。 變更偵測邏輯會根據所有集合變更進行更新,即使這不會影響特定的索引值也一樣。 這是因為接聽邏輯在集合的所有執行個體中很常見。
附加屬性
若要繫結至附加屬性,您必須將類別和屬性名稱放在點之後的括弧中。 例如,Text="{x:Bind Button22.(Grid.Row)}"。 如果屬性未在 Xaml 命名空間中宣告,則必須使用 xml 命名空間作為前置詞,您應該對應至檔前端的程式代碼命名空間。
轉型
編譯的繫結是強類型的,並將解析路徑中每個步驟的類型。 如果傳回的類型沒有成員,在編譯階段將會失敗。 您可以指定轉換來告訴繫結物件的實際類型。
在下面的範例中,obj 是一個物件類型的屬性,但包含一個文字方塊,所以我們可以使用 Text="{x:Bind ((TextBox)obj).Text}" 或 Text="{x:Bind obj.(TextBox.Text)}"。
Text="{x:Bind ((data:SampleDataGroup)groups3[0]).Title}" 中的 groups3 欄位是物件字典,因此您必須將其轉換為 data:SampleDataGroup。 請注意,使用 data: 命名空間前置詞,將物件類型對應到不屬於預設 XAML 命名空間的程式碼命名空間。
注意:C# 樣式轉換語法比附加屬性語法更有彈性,而且是未來建議的語法。
無路徑轉換
本機繫結剖析器不提供關鍵字來表示 this
為函式參數,但它支援無路徑轉換 (例如 {x:Bind (x:String)}
),可以用做函式參數。 因此,{x:Bind MethodName((namespace:TypeOfThis))}
是執行概念上等同於 {x:Bind MethodName(this)}
的有效方式。
範例:
Text="{x:Bind local:MainPage.GenerateSongTitle((local:SongItem))}"
<Page
x:Class="AppSample.MainPage"
...
xmlns:local="using:AppSample">
<Grid>
<ListView ItemsSource="{x:Bind Songs}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:SongItem">
<TextBlock
Margin="12"
FontSize="40"
Text="{x:Bind local:MainPage.GenerateSongTitle((local:SongItem))}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Page>
namespace AppSample
{
public class SongItem
{
public string TrackName { get; private set; }
public string ArtistName { get; private set; }
public SongItem(string trackName, string artistName)
{
ArtistName = artistName;
TrackName = trackName;
}
}
public sealed partial class MainPage : Page
{
public List<SongItem> Songs { get; }
public MainPage()
{
Songs = new List<SongItem>()
{
new SongItem("Track 1", "Artist 1"),
new SongItem("Track 2", "Artist 2"),
new SongItem("Track 3", "Artist 3")
};
this.InitializeComponent();
}
public static string GenerateSongTitle(SongItem song)
{
return $"{song.TrackName} - {song.ArtistName}";
}
}
}
繫結路徑中的函式
從 Windows 10 版本 1607 開始,{x:Bind} 支援使用函式做為繫結路徑的分葉步驟。 這是資料繫結的強大功能,可在標記中啟用數個案例。 如需詳細資訊,請參閱函式繫結 。
事件繫結
事件繫結是已編譯繫結的唯一功能。 它可讓您使用繫結來指定事件的處理常式,而不需要在程式碼後置上指定方法。 例如:Click="{x:Bind rootFrame.GoForward}"。
針對事件,目標方法不得多載,也必須:
- 符合事件的簽章。
- OR 沒有參數。
- OR 具有可從事件參數類型指派的相同類型參數數目。
在產生的程式碼後置中,編譯的繫結會處理事件,並將它路由至模型上的方法,並在事件發生時評估繫結運算式的路徑。 這表示,不同於屬性繫結,它不會追蹤模型的變更。
有關屬性路徑的字串語法的詳細資訊,請參閱屬性路徑語法,並記住此處描述的 {x:Bind} 的差異。
您可以使用 {x:Bind} 設定的屬性
{x:Bind} 使用 bindingProperties 預留位置符語法進行說明,因為可以在標記延伸中設定多個讀/寫屬性。 可以使用逗號分隔的 propName=value 配對以任意順序設定屬性。 請注意,您無法在繫結運算式中包含分行符號。 某些屬性需要沒有類型轉換的類型,因此這些屬性需要以巢狀方式置於 {x:Bind} 中的自己的標記延伸。
這些屬性的運作方式與 Binding 類別的屬性大致相同。
屬性 | 說明 |
---|---|
路徑 | 請參閱上面的屬性路徑區段。 |
轉換器 | 指定繫結引擎所呼叫的轉換器物件。 轉換器可以在 XAML 中設定,但只有在您參考資源字典中指派給該物件的 {StaticResource} 標記延伸參考時,才能參考該物件。 |
ConverterLanguage | 指定轉換器要使用的文化特性。 (如果您要設定 ConverterLanguage 您也應該設定 Converter。) 文化被設定為以標準為基礎的識別碼。 如需詳細資訊,請參閱 ConverterLanguage。 |
ConverterParameter | 指定可在轉換器邏輯中使用的轉換器參數。 (如果您要設定 ConverterParameter,您也應該設定 Converter。) 大部分轉換器都會使用簡單的邏輯,從傳遞的值取得其所需的所有資訊來轉換,而且不需要 ConverterParameter 值。 ConverterParameter 參數適用於中等進階的轉換器實作,該實作具有多個邏輯來關閉 ConverterParameter 中傳遞的內容。 您可以編寫一個使用字串以外的值的轉換器,但這並不常見,請參閱 ConverterParameter 中的備註以獲取更多資訊。 |
FallbackValue | 指定要在無法解析來源或路徑時顯示的值。 |
模式 | 將繫結模式指定為下列其中一個字串:「OneTime」、「OneWay」或「TwoWay」。 預設值為「OneTime」。 請注意,這與 {Binding} 的預設值不同,在大部分情況下為「OneWay」。 |
TargetNullValue | 指定當來源值解析但明確為 null 時要顯示的值。 |
BindBack | 指定要用於雙向繫結反向方向的函式。 |
UpdateSourceTrigger | 指定何時將變更從控制項推送回 TwoWay 繫結中的模型。 除 TextBox.Text 以外的所有屬性的預設值都是 PropertyChanged;TextBox.Text 為 LostFocus。 |
注意
如果您要將標記從 {Binding} 轉換為 {x:Bind},請注意 Mode 屬性預設值的差異。 x:DefaultBindMode 可用來變更標記樹狀結構特定區段的 x:Bind 的預設模式。 選取的模式將在該元素及其下層上套用任何 x:Bind 運算式,這些運算式不會明確指定模式為繫結的一部分。 OneTime 比 OneWay 更有效能,因為使用 OneWay 會導致產生更多程式碼來連結及處理變更偵測。
備註
因為 {x:Bind} 會使用產生的程式碼來達到其優點,所以在編譯階段需要類型資訊。 這表示您無法繫結至您事先不知道類型的屬性。 因此,您不能將 {x:Bind} 與 DataContext 屬性一起使用,該屬性的類型為 Object,並且也可能在執行階段發生變更。
搭配資料範本使用 {x:Bind} 時,您必須藉由設定 x:DataType 值來指出繫結的類型,如範例一節所示。 您也可以將類型設定為介面或基底類別類型,然後視需要使用轉換來制定完整運算式。
編譯的繫結取決於程式碼產生。 因此,如果您在資源字典中使用 {x:Bind},則資源字典必須有程式碼後置類別。 如需程式碼範例,請參閱使用 {x:Bind} 的資源字典。
包含已編譯繫結的頁面和使用者控制項會在產生的程式碼中具有「繫結」屬性。 這包含下列方法:
- Update() - 這會更新所有已編譯繫結的值。 任何單向/雙向繫結都會讓接聽程式連結以偵測變更。
- Initialize() - 如果繫結尚未初始化,則它將呼叫 Update() 來初始化繫結
- StopTracking() - 這會取消針對單向和雙向繫結建立的所有接聽程式。 您可以使用 Update() 方法來重新初始化它們。
注意
從 Windows 10 版本 1607 開始,XAML 架構針對可見度轉換器提供了內建布林值。 轉換器將 true 對應到 Visible 列舉值,將 false 對應到 Collapsed,因此您可以將可見度屬性繫結到布林值,而無需建立轉換器。 請注意,這不是函式繫結的功能,只有屬性繫結。 若要使用內建轉換器,您應用程式的最低目標 SDK 版本必須為 14393 或更新版本。 若您的應用程式是以舊版 Windows 10 為目標,您就無法使用此轉換器。 如需目標版本的詳細資訊,請參閱版本調適型程式碼 (機器翻譯)。
訣竅:如果需要為值指定單一大括號 (例如在 Path 或 ConverterParameter 中),請在其前面加上反斜線:\{
。 或者,將包含需要逸出的大括號的整個字串括在輔助引號集中,例如 ConverterParameter='{Mix}'
。
Converter、ConverterLanguage 和 ConverterLanguage,都與將繫結來源中的值或類型轉換為與繫結目標屬性相容的類型或值的案例相關。 如需詳細資訊和範例,請參閱深入瞭解資料繫結區段。
{x:Bind} 只是標記延伸,無法以程式設計方式建立或操作這類繫結。 有關標記延伸的詳細資訊,請參閱 XAML 概觀。