深入了解資料繫結

重要 API

注意

本主題詳細說明資料繫結功能。 如需簡短的實用介紹,請參閱資料繫結概觀

本主題與位於 Windows.UI.Xaml.Data 命名空間 (機器翻譯) 之 API 的資料繫結有關。

資料繫結可讓您的應用程式 UI 顯示資料,以及選擇性地與該資料保持同步。 資料繫結可讓您將資料與 UI 分開考量,為應用程式建構更簡單的概念模型,以及更好的可讀性、測試性和維護性。

第一次顯示 UI 時,您可以使用資料繫結單純顯示資料來源的值,但不回應這些值中的變更。 這是一種繫結模式,稱為「一次性」,而且適用於在執行階段期間不會變更的值。 或者,您可以選擇「觀察」這些值,並於值變更時更新 UI。 此模式稱為「單向」,適用於唯讀資料。 最後,您可以選擇觀察和更新,讓使用者對 UI 中的值所做的變更自動推送回資料來源。 此模式稱為「雙向」,適用於讀寫資料。 以下列出一些範例。

  • 您可以使用一次性模式將 Image \(英文\) 繫結到目前使用者的相片。
  • 您可以使用單向模式將 ListView \(英文\) 繫結到依報紙區段分組的即時新聞文章集合。
  • 您可以使用雙向模式將 TextBox \(英文\) 繫結到表單中的客戶名稱。

與模式無關,繫結有兩種,通常都在 UI 標記中宣告。 您可以選擇使用 {x:Bind} 標記延伸 (機器翻譯) 或 {Binding} 標記延伸 (機器翻譯), 甚至可以在同一個應用程式中,或是在同一個 UI 元素中混合使用兩者。 {x:Bind} 是 Windows 10 新增的標記,效能更好。 本主題中介紹的所有詳細資訊都適用於這兩種繫結,除非我們明確表示另有規定。

示範 {x:Bind} 的範例應用程式

示範 {Binding} 的範例應用程式

每個繫結都涉及下列項目

  • 繫結來源: 這是指繫結的資料來源,只要類別中的成員含有您想在 UI 中顯示的值,該類別的執行個體即可作為來源。
  • 繫結目標: 這是 UI 中顯示資料的 FrameworkElementDependencyProperty
  • 繫結物件: 這是指將資料值從來源傳輸到目標,並選擇性地從目標傳回來源的部分。 繫結物件是透過您的 {x:Bind} (機器翻譯) 或 {Binding} (機器翻譯) 標記延伸,於 XAML 載入時間建立的。

在下列各節中,我們會進一步介紹繫結來源、繫結目標及繫結物件, 並透過將按鈕內容繫結至名為 NextButtonText (屬於名為 HostViewModel 的類別) 的字串屬性範例,將這些區段連結在一起。

繫結來源

以下是一個非常基本的類別實作,可用作繫結來源。

如果您使用 C++/WinRT,請將新的 Midl 檔案 (.idl) 項目加入專案中,如下列 C++/WinRT 程式碼範例所示。 以清單中顯示的 MIDL 3.0 程式碼取代那些新檔案的內容、建置專案以產生 HostViewModel.h.cpp,然後將程式碼新增至產生的檔案,以符合清單。 如需有關那些產生的檔案以及如何將其複製到專案中的詳細資訊,請參閱 XAML 控制項;繫結至一個 C++/WinRT 屬性

public class HostViewModel
{
    public HostViewModel()
    {
        this.NextButtonText = "Next";
    }

    public string NextButtonText { get; set; }
}
// HostViewModel.idl
namespace DataBindingInDepth
{
    runtimeclass HostViewModel
    {
        HostViewModel();
        String NextButtonText;
    }
}

// HostViewModel.h
// Implement the constructor like this, and add this field:
...
HostViewModel() : m_nextButtonText{ L"Next" } {}
...
private:
    std::wstring m_nextButtonText;
...

// HostViewModel.cpp
// Implement like this:
...
hstring HostViewModel::NextButtonText()
{
    return hstring{ m_nextButtonText };
}

void HostViewModel::NextButtonText(hstring const& value)
{
    m_nextButtonText = value;
}
...

HostViewModel 及其屬性 NextButtonText 的實作,僅適用於單次繫結。 不過,單向和雙向繫結十分常見,在這些繫結類型中,UI 會自動更新以回應繫結來源資料值的變更, 為了讓這些類型的繫結正常運作,您必須讓繫結物件「能夠觀察」繫結來源。 因此,在我們的範例中,如果我們想要單向或雙向繫結至 NextButtonText 屬性,就必須讓繫結物件能夠觀察該屬性的值在執行階段發生的所有變更。

其中一種作法是衍生類別,該類別代表來自 DependencyObject (機器翻譯) 的繫結來源,並透過 DependencyProperty (機器翻譯) 公開資料值, 這就是將 FrameworkElement (機器翻譯) 變成可觀察的方式。 FrameworkElements 是立即可用的優良繫結來源。

將類別變成可觀察 (且對已經有基底類別的類別而言為必要) 的輕量型方法,是實作 System.ComponentModel.INotifyPropertyChanged (機器翻譯), 這實際上只涉及實作名為 PropertyChanged 的單一事件。 使用 HostViewModel 的範例如下。

...
using System.ComponentModel;
using System.Runtime.CompilerServices;
...
public class HostViewModel : INotifyPropertyChanged
{
    private string nextButtonText;

    public event PropertyChangedEventHandler PropertyChanged = delegate { };

    public HostViewModel()
    {
        this.NextButtonText = "Next";
    }

    public string NextButtonText
    {
        get { return this.nextButtonText; }
        set
        {
            this.nextButtonText = value;
            this.OnPropertyChanged();
        }
    }

    public void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        // Raise the PropertyChanged event, passing the name of the property whose value has changed.
        this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
// HostViewModel.idl
namespace DataBindingInDepth
{
    runtimeclass HostViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
    {
        HostViewModel();
        String NextButtonText;
    }
}

// HostViewModel.h
// Add this field:
...
    winrt::event_token PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler);
    void PropertyChanged(winrt::event_token const& token) noexcept;

private:
    winrt::event<Windows::UI::Xaml::Data::PropertyChangedEventHandler> m_propertyChanged;
...

// HostViewModel.cpp
// Implement like this:
...
void HostViewModel::NextButtonText(hstring const& value)
{
    if (m_nextButtonText != value)
    {
        m_nextButtonText = value;
        m_propertyChanged(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"NextButtonText" });
    }
}

winrt::event_token HostViewModel::PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler)
{
    return m_propertyChanged.add(handler);
}

void HostViewModel::PropertyChanged(winrt::event_token const& token) noexcept
{
    m_propertyChanged.remove(token);
}
...

現在 NextButtonText 屬性已變成可觀察。 當您撰寫該屬性的單向或雙向繫結時 (稍後將展示方法),產生的繫結物件會訂閱 PropertyChanged 事件。 產生該事件時,繫結物件的處理常式會收到包含已變更屬性名稱的引數, 如此繫結物件便知道要取得哪個屬性值,並再次讀取。

因此,您不需要實作上述模式許多次,如果您使用的是 C#,則直接衍生自 QuizGame \(英文\) 範例 (在 "Common" 資料夾) 中的 BindableBase 基底類別即可。 以下是其做法範例。

public class HostViewModel : BindableBase
{
    private string nextButtonText;

    public HostViewModel()
    {
        this.NextButtonText = "Next";
    }

    public string NextButtonText
    {
        get { return this.nextButtonText; }
        set { this.SetProperty(ref this.nextButtonText, value); }
    }
}
// Your BindableBase base class should itself derive from Windows::UI::Xaml::DependencyObject. Then, in HostViewModel.idl, derive from BindableBase instead of implementing INotifyPropertyChanged.

注意

針對 C++/WinRT,從基底類別衍生的任何執行階段類別 (您在您的應用程式中宣告),都稱為「可組合」類別。 而且有以可組合的類別為主的條件約束。 若要讓應用程式通過 Visual Studio 和 Microsoft Store 所使用的 Windows 應用程式認證套件測試來驗證提交 (因而讓應用程式成功擷取到 Microsoft Store 中),可組合的類別必須最終衍生自 Windows 基底類別。 這表示位於繼承階層根目錄的類別必須是源自 Windows.* 命名空間的類型。 如果您真的需要從基底類別衍生執行階段類別 (例如針對衍生來源的所有檢視模型實作 BindableBase 類別),可以從 Windows.UI.Xaml.DependencyObject (機器翻譯) 衍生。

使用 String.Empty (機器翻譯) 或 null 引數引發 PropertyChanged 事件,表示應該重新讀取物件上的所有非索引子屬性。 您可以針對特定索引子使用引數 "Item[indexer]" (「indexer」為索引值),或針對所有索引子使用值 "Item[]",以引發事件來指出物件上的索引子屬性已變更。

繫結來源可以視為屬性包含資料的單一物件,或是物件集合。 在 C# 與 Visual Basic 程式碼中,您可以一次性繫結到實作 List(Of T) \(部分機器翻譯\) 的物件,以顯示不會在執行階段變更的集合。 對於可觀察的集合 (在集合中新增和移除項目時觀察),請改為單向繫結至 ObservableCollection(Of T) (機器翻譯)。 在 C++/CX 程式碼中,針對可觀察和不可觀察的集合,您都可以繫結到 Vector<T> \(部分機器翻譯\),且 C++/WinRT 具有自己的類型。 若要繫結至您自己的集合類別,請參考下表中的指導方針。

案例 C# 與 VB (CLR) C++/WinRT C++/CX
繫結至物件。 可為任何物件。 可為任何物件。 物件必須有 BindableAttribute (機器翻譯) 或者實作 ICustomPropertyProvider (機器翻譯)。
取得繫結物件的屬性變更通知。 物件必須實作 INotifyPropertyChanged \(部分機器翻譯\)。 物件必須實作 INotifyPropertyChanged \(部分機器翻譯\)。 物件必須實作 INotifyPropertyChanged \(部分機器翻譯\)。
繫結至集合。 List(Of T) \(部分機器翻譯\) IInspectableIVector,或者 IBindableObservableVector。 請參閱 XAML 項目控制項;繫結至 C++/WinRT 集合使用 C++/WinRT 的集合 Vector<T> \(部分機器翻譯\)
取得繫結集合的集合變更通知。 ObservableCollection(Of T) \(部分機器翻譯\) IInspectableIObservableVector。 例如,winrt::single_threaded_observable_vector<T> \(部分機器翻譯\)。 IObservableVector<T> \(英文\)。 Vector<T> \(部分機器翻譯\) 會實作這個介面。
實作支援繫結的集合。 擴充 List(Of T) (機器翻譯),或者實作 IList (機器翻譯)、IList(Of Object) (機器翻譯)、IEnumerable (機器翻譯) 或 IEnumerable(Of Object) (機器翻譯)。 不支援繫結至泛型 IList(Of T)IEnumerable(Of T) 實作 IInspectableIVector。 請參閱 XAML 項目控制項;繫結至 C++/WinRT 集合使用 C++/WinRT 的集合 實作 IBindableVector (機器翻譯)、IBindableIterable (機器翻譯)、IVector<Object^> (機器翻譯)、IIterable<Object^> (機器翻譯)、IVector<IInspectable*> (機器翻譯) 或 IIterable<IInspectable*>。 不支援繫結至泛型 IVector<T>IIterable<T>
實作可支援集合變更通知的集合。 擴充 ObservableCollection(Of T) (機器翻譯) 或者實作 (非泛型) IList (機器翻譯) 與 INotifyCollectionChanged (機器翻譯)。 實作 IInspectableIObservableVector,或 IBindableObservableVector 實作 IBindableVector (機器翻譯) 與 IBindableObservableVector (機器翻譯)
實作支援累加式載入的集合。 擴充 ObservableCollection(Of T) (機器翻譯) 或者實作 (非泛型) IList (機器翻譯) 與 INotifyCollectionChanged (機器翻譯)。 此外,也實作 ISupportIncrementalLoading (機器翻譯) 實作 IInspectableIObservableVector,或 IBindableObservableVector。 此外,也實作 ISupportIncrementalLoading \(英文\) 實作 IBindableVector (機器翻譯)、IBindableObservableVector (機器翻譯) 與 ISupportIncrementalLoading (機器翻譯)。

您可以使用累加式載入,將清單控制項繫結至任意大型資料來源,且仍能具有高效能。 舉例來說,您可以將清單控制項繫結至 Bing 影像查詢結果,但不需要一次載入所有結果, 相反地,您只會立即載入某些結果,並視需要載入其他結果。 若要支援增量載入,您必須在支援集合變更通知的資料來源上實作 ISupportIncrementalLoading \(英文\)。 當資料繫結引擎要求更多資料時,您的資料來源必須提出適當的要求、整合結果,然後傳送適當的通知以更新 UI。

繫結目標

在下列兩個範例中,Button.Content 屬性是繫結目標,而其值設定為宣告繫結物件的標記延伸模組。 第一個範例顯示 {x:Bind} (機器翻譯),第二個範例則是 {Binding} (機器翻譯)。 在標記中宣告繫結是常見案例 (便利、可讀取且可使用工具), 但是如有需要,您可以避免使用標記,改為以命令方式 (程式設計方式) 建立 Binding (機器翻譯) 類別的執行個體。

<Button Content="{x:Bind ...}" ... />
<Button Content="{Binding ...}" ... />

如果您使用 C++/WinRT 或 Visual C++ 元件延伸 (C++/CX),則需要將 BindableAttribute (機器翻譯) 屬性新增至您要搭配 {Binding} (機器翻譯) 標記延伸使用的任何執行階段類別。

重要

如果您使用的是 C++/WinRT,則可以使用 BindableAttribute \(英文\) 屬性 (如果您安裝了 Windows SDK 版本 10.0.17763.0 (Windows 10 版本 1809) 或更新版本)。 如果沒有該屬性,則需要實作 ICustomPropertyProviderICustomProperty 介面,才能使用 {Binding} 標記延伸。

使用 {x:Bind} 宣告的繫結物件

在撰寫 {x:Bind} (機器翻譯) 標記之前,還需要執行一個步驟。 我們必須從代表標記頁面的類別中公開繫結來源類別。 作法是在 MainPage 頁面類別中新增屬性 (在此案例中為 HostViewModel 類型)。

namespace DataBindingInDepth
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            this.ViewModel = new HostViewModel();
        }
    
        public HostViewModel ViewModel { get; set; }
    }
}
// MainPage.idl
import "HostViewModel.idl";

namespace DataBindingInDepth
{
    runtimeclass MainPage : Windows.UI.Xaml.Controls.Page
    {
        MainPage();
        HostViewModel ViewModel{ get; };
    }
}

// MainPage.h
// Include a header, and add this field:
...
#include "HostViewModel.h"
...
    DataBindingInDepth::HostViewModel ViewModel();

private:
    DataBindingInDepth::HostViewModel m_viewModel{ nullptr };
...

// MainPage.cpp
// Implement like this:
...
MainPage::MainPage()
{
    InitializeComponent();

}

DataBindingInDepth::HostViewModel MainPage::ViewModel()
{
    return m_viewModel;
}
...

完成這個步驟後,現在我們可以進一步瞭解用於宣告繫結物件的標記。 下列範例使用稍早在「繫結目標」一節中用過的相同 Button.Content 繫結目標,並顯示該目標已繫結至 HostViewModel.NextButtonText 屬性。

<!-- MainPage.xaml -->
<Page x:Class="DataBindingInDepth.Mainpage" ... >
    <Button Content="{x:Bind Path=ViewModel.NextButtonText, Mode=OneWay}" ... />
</Page>

請注意我們為 Path 指定的值。 這個值是從頁面本身的角度來解譯,在此案例中,路徑最初會參考我們剛才加入至 MainPage 頁面的屬性 ViewModel。 該屬性會傳回 HostViewModel 執行個體,因此我們可以進入該物件,以存取 HostViewModel.NextButtonText 屬性。 我們也會指定 Mode 以覆寫 {x:Bind} 的單次預設值。

Path (機器翻譯) 屬性支援使用多種語法選項繫結至巢狀屬性、附加屬性,以及整數和字串索引子。 如需詳細資訊,請參閱 Property-path 語法 (機器翻譯)。 繫結至字串索引子可製造繫結至動態屬性的效果,但無須實作 ICustomPropertyProvider。 如需瞭解其他設定,請參閱 {x:Bind} 標記延伸 (機器翻譯)。

為了說明 HostViewModel.NextButtonText 屬性確實是可觀察的,請將 Click 事件處理常式新增至按鈕,然後更新 HostViewModel.NextButtonText 的值。 建置、執行,然後按一下按鈕以查看按鈕內容更新的值。

// MainPage.xaml.cs
private void Button_Click(object sender, RoutedEventArgs e)
{
    this.ViewModel.NextButtonText = "Updated Next button text";
}
// MainPage.cpp
void MainPage::ClickHandler(IInspectable const&, RoutedEventArgs const&)
{
    ViewModel().NextButtonText(L"Updated Next button text");
}

注意

TextBox \(英文\) 失去焦點時 (不是在使用者每次按下按鍵之後),即會將對於 TextBox.Text \(英文\) 的變更傳送到雙向繫結來源。

DataTemplate 與 x:DataType

DataTemplate (機器翻譯) 內 (無論是作為項目範本、內容範本或標頭範本),Path 的值不會在頁面內容中解譯,而是在範本化的資料物件內容中解譯。 在資料範本中使用 {x:Bind},以便在編譯階段驗證其繫結 (並為繫結產生有效率的程式碼)。這時 DataTemplate 必須使用 x:DataType 宣告其資料物件的類型。 下列範例可用作繫結至 SampleDataGroup 物件集合之項目控制項的 ItemTemplate

<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>

Path 中的弱式類型物件

假設您有名為 SampleDataGroup 的類型,會實作名為 Title 的字串屬性, 而您有一個屬性 MainPage.SampleDataGroupAsObject,其屬於類型物件,但會自動傳回 SampleDataGroup 的執行個體。 繫結的 <TextBlock Text="{x:Bind SampleDataGroupAsObject.Title}"/> 會造成編譯錯誤,因為在類型物件上找不到 Title 屬性。 解決此問題的方法是為您的 Path 語法新增轉換,如下所示:<TextBlock Text="{x:Bind ((data:SampleDataGroup)SampleDataGroupAsObject).Title}"/>。 以下是另一個範例,其中 Element 宣告為 Object,但實際上是 TextBlock:<TextBlock Text="{x:Bind Element.Text}"/> 新增轉換同樣可解決此問題:<TextBlock Text="{x:Bind ((TextBlock)Element).Text}"/>

如果您的資料會以非同步方式載入

支援 {x:Bind} 的程式碼會在您頁面的部分類別中於編譯階段產生。 您可以在 obj 資料夾中找到這些檔案,名稱如下 (適用於 C#):<view name>.g.cs。 產生的程式碼包含頁面的 Loading (機器翻譯) 事件的處理常式,而該處理常式會在代表頁面繫結的已產生類別上呼叫 Initialize 方法。 接著 Initialize 會呼叫 Update,開始在繫結來源與目標之間移動資料。 Loading 會恰好在頁面或使用者控制項的第一個度量階段之前引發, 因此,如果您的資料是以非同步方式載入,在呼叫 Initialize 時可能會來不及準備就緒。 為避免發生這種情況,載入資料之後,您可以呼叫 this.Bindings.Update(); 以強制初始化單次繫結。 如果您只需要針對以非同步方式載入的資料使用一次性繫結,則將其初始化的方法會比讓其擁有單向繫結並接聽變更來得經濟實惠。 如果您的資料沒有精細的變更,且可能會在特定動作中更新,您可以進行單次繫結,並隨時透過呼叫 Update 強制手動更新。

注意

{x:Bind} 不適合用於晚期繫結案例,例如瀏覽 JSON 物件或鴨子型別的字典結構。 「鴨子型別」是以屬性名稱的語彙相符項目為基礎的弱形式類型 (「如果一隻鳥走路像鴨子,游泳起來像鴨子,叫起來也像鴨子,那隻鳥就是鴨子」)。 使用鴨子型別,Age 屬性的繫結同樣可滿足 PersonWine 物件 (假設那些類型都有 Age 屬性)。 在這些情況下,請使用 {Binding} 標記延伸模組。

使用 {Binding} 宣告的繫結物件

如果您使用 C++/WinRT 或 Visual C++ 元件延伸 (C++/CX),必須先將 BindableAttribute (機器翻譯) 屬性新增至您希望繫結的任何執行階段類別,才能使用 {Binding} (機器翻譯) 標記延伸模組。 若要使用 {x:Bind},您不需要該屬性。

// HostViewModel.idl
// Add this attribute:
[Windows.UI.Xaml.Data.Bindable]
runtimeclass HostViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
...

重要

如果您使用的是 C++/WinRT,則可以使用 BindableAttribute \(英文\) 屬性 (如果您安裝了 Windows SDK 版本 10.0.17763.0 (Windows 10 版本 1809) 或更新版本)。 如果沒有該屬性,則需要實作 ICustomPropertyProviderICustomProperty 介面,才能使用 {Binding} 標記延伸。

根據預設,{Binding} (機器翻譯) 會假設您繫結至標記頁面的 DataCoNtext (機器翻譯)。 因此,我們將頁面的 DataContext 設定為繫結來源類別的執行個體 (在此案例中為 HostViewModel 類型)。 下列範例顯示宣告繫結物件的標記。 我們使用稍早在「繫結目標」一節中用過的相同 Button.Content 繫結目標,並繫結至 HostViewModel.NextButtonText 屬性。

<Page xmlns:viewmodel="using:DataBindingInDepth" ... >
    <Page.DataContext>
        <viewmodel:HostViewModel x:Name="viewModelInDataContext"/>
    </Page.DataContext>
    ...
    <Button Content="{Binding Path=NextButtonText}" ... />
</Page>
// MainPage.xaml.cs
private void Button_Click(object sender, RoutedEventArgs e)
{
    this.viewModelInDataContext.NextButtonText = "Updated Next button text";
}
// MainPage.cpp
void MainPage::ClickHandler(IInspectable const&, RoutedEventArgs const&)
{
    viewModelInDataContext().NextButtonText(L"Updated Next button text");
}

請注意我們為 Path 指定的值。 這個值會在頁面內容的 DataCoNtext (機器翻譯) 中解譯,該屬性在此範例中設定為 HostViewModel 的執行個體。 路徑會參考 HostViewModel.NextButtonText 屬性。 Mode 可以省略,因為此處使用 {Binding} 的單向預設值。

UI 元素的 DataCoNtext (機器翻譯) 預設值是其父系的繼承值。 您當然可以藉由明確設定 DataContext 覆寫該預設值,修改過的值預設會由子系繼承。 當您想要有多個使用相同來源的繫結時,在元素上明確設定 DataContext 很實用。

繫結物件具有 Source 屬性,預設為 UI 元素的 DataContext (機器翻譯),該元素上的繫結已宣告。 您可以藉由在繫結上明確設定 SourceRelativeSourceElementName 來覆寫此預設值 (如需詳細資訊,請參閱 {Binding} (機器翻譯))。

DataTemplate \(英文\) 內,DataContext \(英文\) 設定為樣板化的資料物件。 下列範例可用作繫結至任何類型集合之項目控制項的 ItemTemplate;類型集合須具有名為 TitleDescription 的字串屬性。

<DataTemplate x:Key="SimpleItemTemplate">
    <StackPanel Orientation="Vertical" Height="50">
      <TextBlock Text="{Binding Title}"/>
      <TextBlock Text="{Binding Description"/>
    </StackPanel>
  </DataTemplate>

注意

根據預設,當 TextBox \(英文\) 失去焦點時,TextBox.Text \(英文\) 的變更會傳送到雙向繫結來源。 若要在每名使用者按鍵輸入之後傳送變更,請在標記中的繫結上將 UpdateSourceTrigger 設定為 PropertyChanged。 您也可以將 UpdateSourceTrigger 設定為 Explicit,以完全控制何時將變更傳送至來源。 接著,您可以在文字方塊中處理事件 (通常是 TextBox.TextChanged (機器翻譯)),呼叫目標上的 GetBindingExpression (機器翻譯) 以取得 BindingExpression (機器翻譯) 物件,最後再呼叫 BindingExpression.UpdateSource (機器翻譯),以程式設計方式更新資料來源。

Path (機器翻譯) 屬性支援使用多種語法選項繫結至巢狀屬性、附加屬性,以及整數和字串索引子。 如需詳細資訊,請參閱 Property-path 語法 (機器翻譯)。 繫結至字串索引子可製造繫結至動態屬性的效果,但無須實作 ICustomPropertyProviderElementName (機器翻譯) 屬性對元素之間的繫結很實用。 RelativeSource (機器翻譯) 屬性有數種用途,其中一個是作為 ControlTemplate (機器翻譯) 內範本繫結的更強大替代屬性。 如需瞭解其他設定,請參閱 {Binding} 標記延伸 (機器翻譯) 與 Binding (機器翻譯) 類別。

如果來源和目標的類型不相同,該怎麼辦?

如果您想要根據布林值屬性的值控制 UI 元素的可見度,或以數值範圍或趨勢函式指定的色彩呈現 UI 元素,抑或是在預期字串的 UI 元素屬性中顯示日期和/或時間值,就必須轉換值的類型。 在某些情況下,正確的解決方案是從繫結來源類別公開正確型別的另一個屬性,並確認轉換邏輯在該處已完成封裝且可進行測試。 但是當您擁有大量來源和目標屬性或其組合時,這種做法既不夠彈性,也不可調整。 在此情況下,您有幾個選項:

  • 如果您使用 {x:Bind},可以直接繫結至函式以執行該轉換
  • 或者,您可以指定值轉換器,這是設計用來執行轉換的物件

值轉換器

以下是適合單次或單向繫結的值轉換器,可將 DateTime (機器翻譯) 值轉換成包含月份的字串值。 這個類別會實作 IValueConverter (機器翻譯)。

public class DateToStringConverter : IValueConverter
{
    // Define the Convert method to convert a DateTime value to 
    // a month string.
    public object Convert(object value, Type targetType, 
        object parameter, string language)
    {
        // value is the data from the source object.
        DateTime thisdate = (DateTime)value;
        int monthnum = thisdate.Month;
        string month;
        switch (monthnum)
        {
            case 1:
                month = "January";
                break;
            case 2:
                month = "February";
                break;
            default:
                month = "Month not found";
                break;
        }
        // Return the value to pass to the target.
        return month;
    }

    // ConvertBack is not implemented for a OneWay binding.
    public object ConvertBack(object value, Type targetType, 
        object parameter, string language)
    {
        throw new NotImplementedException();
    }
}
// See the "Formatting or converting data values for display" section in the "Data binding overview" topic.

以下方法可在繫結物件標記中取用該值轉換器。

<UserControl.Resources>
  <local:DateToStringConverter x:Key="Converter1"/>
</UserControl.Resources>
...
<TextBlock Grid.Column="0" 
  Text="{x:Bind ViewModel.Month, Converter={StaticResource Converter1}}"/>
<TextBlock Grid.Column="0" 
  Text="{Binding Month, Converter={StaticResource Converter1}}"/>

若繫結的 Converter (機器翻譯) 參數已經定義,繫結引擎會呼叫 Convert (機器翻譯) 與 ConvertBack (機器翻譯) 方法。 從來源傳遞資料時,繫結引擎會呼叫 Convert,並將傳回的資料傳遞至目標。 從目標傳遞資料時 (針對雙向繫結),繫結引擎會呼叫 ConvertBack,並將傳回的資料傳遞至來源。

轉換器也有選用的參數:ConverterLanguage (機器翻譯) 可以指定轉換作業中要使用的語言,而 ConverterParameter (機器翻譯) 可允許傳遞轉換邏輯的參數。 如需使用轉換器參數的範例,請參閱 IValueConverter (機器翻譯)。

注意

如果轉換中出現錯誤,請不要擲回例外狀況。 請改為傳回 DependencyProperty.UnsetValue (機器翻譯) 以停止資料傳輸。

若要在無法解析繫結來源時顯示要使用的預設值,請在標記中設定繫結物件的 FallbackValue 屬性, 這種做法很適合用於處理轉換和格式化錯誤。 繫結至可能不存在於異質類型繫結集合中所有物件上的來源屬性,也可以派上用場。

如果您將文字控制項繫結至不是字串的值,資料繫結引擎會將該值轉換成字串。 如果該值為參考類型,資料繫結引擎會呼叫 ICustomPropertyProvider.GetStringRepresentation (機器翻譯) 或 IStringable.ToString (機器翻譯) (如果有的話),否則會呼叫 Object.ToString (機器翻譯) 以擷取字串值。 不過請注意,繫結引擎會忽略隱藏基底類型實作的任何 ToString 實作, 子類別實作必須覆寫基底類型 ToString 方法。 同樣地,在原生語言中,所有受控物件似乎都會實作 ICustomPropertyProvider (機器翻譯) 與 IStringable (機器翻譯), 不過,對 GetStringRepresentationIStringable.ToString 的呼叫全部都會路由傳送至 Object.ToString 或該方法的覆寫,永遠不會路由傳送至隱藏基底類型實作的新 ToString 實作。

注意

從 Windows 10 版本 1607 開始,XAML 架構針對可見度轉換器提供內建布林值。 該轉換器會將 true 對應至 Visible 列舉值,並將 false 對應至 Collapsed,這樣您就可以將 Visibility 屬性繫結至布林值而不用建立轉換器。 若要使用內建轉換器,您應用程式的最低目標 SDK 版本必須為 14393 或更新版本。 若您的應用程式是以舊版 Windows 10 為目標,您就無法使用此轉換器。 如需目標版本的詳細資訊,請參閱版本調適型程式碼 (機器翻譯)。

{x:Bind} 中的函式繫結

{x:Bind} 可將繫結路徑中的最後一個步驟變成函式。 這種做法可用於執行轉換,以及執行相依於多個屬性的繫結。 請參閱 x:Bind 中的函式

元素繫結

您可以將一個 XAML 元素的屬性繫結至另一個 XAML 元素的屬性。 以下是其在標記中的作法範例。

<TextBox x:Name="myTextBox" />
<TextBlock Text="{x:Bind myTextBox.Text, Mode=OneWay}" />

重要

如需使用 C++/WinRT 之元素對元素繫結的必要工作流程,請參閱元素對元素繫結

資源字典與 {x:Bind}

{x:Bind} 標記延伸 (機器翻譯) 相依於程式碼產生,因此需要包含會呼叫 InitializeComponent 建構函式的程式碼後置檔案 (用於初始化產生的程式碼)。 您可以藉由具現化其類型 (以便呼叫 InitializeComponent) 來重複使用資源字典,而不是參考其檔名。 以下範例示範在擁有現有資源字典,並想要在其中使用 {x:Bind} 時該怎麼做。

TemplatesResourceDictionary.xaml

<ResourceDictionary
    x:Class="ExampleNamespace.TemplatesResourceDictionary"
    .....
    xmlns:examplenamespace="using:ExampleNamespace">
    
    <DataTemplate x:Key="EmployeeTemplate" x:DataType="examplenamespace:IEmployee">
        <Grid>
            <TextBlock Text="{x:Bind Name}"/>
        </Grid>
    </DataTemplate>
</ResourceDictionary>

TemplatesResourceDictionary.xaml.cs

using Windows.UI.Xaml.Data;
 
namespace ExampleNamespace
{
    public partial class TemplatesResourceDictionary
    {
        public TemplatesResourceDictionary()
        {
            InitializeComponent();
        }
    }
}

MainPage.xaml

<Page x:Class="ExampleNamespace.MainPage"
    ....
    xmlns:examplenamespace="using:ExampleNamespace">

    <Page.Resources>
        <ResourceDictionary>
            .... 
            <ResourceDictionary.MergedDictionaries>
                <examplenamespace:TemplatesResourceDictionary/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Page.Resources>
</Page>

事件繫結與 ICommand

{x:Bind} (機器翻譯) 支援稱為「事件繫結」的功能。 透過這項功能,您可以使用繫結來指定事件的處理常式,讓您除了使用程式碼後置檔案中的方法外,還能採用其他方式處理事件。 假如您的 MainPage 類別具有 RootFrame 屬性。

public sealed partial class MainPage : Page
{
    ...
    public Frame RootFrame { get { return Window.Current.Content as Frame; } }
}

您可以透過這種方式,將按鈕的 Click 事件繫結至 RootFrame 屬性所傳回之 Frame 物件中的方法。 請注意,我們也會將按鈕的 IsEnabled 屬性繫結至相同 Frame 的另一個成員。

<AppBarButton Icon="Forward" IsCompact="True"
IsEnabled="{x:Bind RootFrame.CanGoForward, Mode=OneWay}"
Click="{x:Bind RootFrame.GoForward}"/>

超載方法無法使用這項技術來處理事件。 此外,如果處理事件的方法具有參數,這些參數必須能夠分別從事件的所有參數類型指派。 在這種情況下,Frame.GoForward (機器翻譯) 不會超載,而且沒有參數 (但即使取用了兩個 object 參數,此方法也依然有效)。 儘管 Frame.GoBack \(英文\) 為多載,我們還是不能透過此技巧使用該方法。

事件繫結技術類似於實作和取用命令 (命令是指傳回實作 ICommand (機器翻譯) 介面之物件的屬性)。 {x:Bind} (機器翻譯) 與 {Binding} (機器翻譯) 都可使用命令。 因此,您不需要多次實作命令模式,可以改為使用 QuizGame (英文) 範例 (位於「Common」資料夾中) 內的 DelegateCommand 協助程式類別。

繫結至資料夾或檔案集合

您可以使用 Windows.Storage (機器翻譯) 命名空間中的 API 擷取資料夾和檔案資料。 不過,GetFilesAsyncGetFoldersAsyncGetItemsAsync 等方法不會傳回適合繫結至清單控制項的值, 您必須改為繫結至 FileInformationFactory (機器翻譯) 類別中的 GetVirtualizedFilesVector (機器翻譯)、GetVirtualizedFoldersVector (機器翻譯) 與 GetVirtualizedItemsVector 方法所傳回的值。 下列來自 StorageDataSource 和 GetVirtualizedFilesVector 範例 (英文) 的程式碼範例顯示一般使用模式。 請記得在應用程式套件資訊清單中宣告 picturesLibrary 功能,並確認圖片媒體櫃資料夾中有圖片。

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    var library = Windows.Storage.KnownFolders.PicturesLibrary;
    var queryOptions = new Windows.Storage.Search.QueryOptions();
    queryOptions.FolderDepth = Windows.Storage.Search.FolderDepth.Deep;
    queryOptions.IndexerOption = Windows.Storage.Search.IndexerOption.UseIndexerWhenAvailable;

    var fileQuery = library.CreateFileQueryWithOptions(queryOptions);

    var fif = new Windows.Storage.BulkAccess.FileInformationFactory(
        fileQuery,
        Windows.Storage.FileProperties.ThumbnailMode.PicturesView,
        190,
        Windows.Storage.FileProperties.ThumbnailOptions.UseCurrentScale,
        false
        );

    var dataSource = fif.GetVirtualizedFilesVector();
    this.PicturesListView.ItemsSource = dataSource;
}

您通常會使用此方法來建立檔案和資料夾資訊的唯讀檢視。 您可以建立檔案和資料夾屬性的雙向繫結,例如讓使用者在音樂檢視中評分歌曲。 不過,在您呼叫適當的 SavePropertiesAsync 方法 (例如 MusicProperties.SavePropertiesAsync (機器翻譯)) 之前,系統不會保存任何變更。 當項目失去焦點時,您必須認可變更,因為這會觸發選取重設。

請注意,使用這項技術的雙向繫結僅適用於索引位置,例如 Music。 您可以透過呼叫 folderInformation.GetIndexedStateAsync (機器翻譯) 方法,判斷位置是否已編製索引。

另請注意,虛擬化向量可以針對某些項目傳回 null,然後再填入其值。 舉例來說,您應該先檢查有沒有 null,再使用繫結至虛擬化向量的清單控制項 SelectedItem (機器翻譯) 值,或改用 SelectedIndex (機器翻譯)。

繫結至依索引鍵分組的資料

如果您取得一般項目集合 (例如書籍,以 BookSku 類別表示) 且使用常見的屬性作為索引鍵將項目分組 (例如 BookSku.AuthorName 屬性),則結果稱為分組資料。 當您將資料分組後,資料就不再是一般集合。 群組資料是群組物件的集合,其中每個群組物件都有

  • 索引鍵,以及
  • 項目的集合,其屬性符合該索引鍵。

若要再次接受書籍範例,依作者姓名對書籍進行分組的結果將得出一個作者姓名群組的集合,其中每個群組都有

  • 索引鍵 (作者名稱),以及
  • BookSku 的集合,其 AuthorName 屬性符合群組的索引鍵。

一般而言,若要顯示集合,您可以將項目控制項 (例如 ListView (機器翻譯) 或 GridView (機器翻譯)) 的 ItemsSource (機器翻譯) 直接繫結至傳回集合的屬性。 如果該集合為一般項目集合,就不需要執行任何特殊動作, 但如果該集合為群組物件的集合 (如同繫結至分組資料時),您便必須使用 CollectionViewSource (機器翻譯) 這項繼物件的服務;此物件位於項目控制項與繫結來源之間。 您可以將 CollectionViewSource 繫結至傳回分組資料的屬性,並將項目控制項繫結至 CollectionViewSourceCollectionViewSource 的額外附加價值是會追蹤目前的項目,因此您可以將多個項目控制項繫結至相同的 CollectionViewSource 以保持同步。 您也可以透過 CollectionViewSource.View (機器翻譯) 屬性所傳回之物件的 ICollectionView.CurrentItem (機器翻譯) 屬性,以程式設計方式存取目前的項目。

若要啟動 CollectionViewSource (機器翻譯) 的分組功能,請將 IsSourceGrouped (機器翻譯) 設為 true。 您是否也需要設定 ItemsPath (機器翻譯) 屬性,取決於您撰寫群組物件的方式。 有兩種方式可以撰寫群組物件:「is-a-group」模式,以及「has-a-group」模式。 在「is-a-group」模式中,群組物件衍生自集合類型 (例如,List<T>),因此群組物件實際上是項目群組本身, 使用此模式時,您不需要設定 ItemsPath。 在「has-a-group」模式中,群組物件具有集合類型的一或多個屬性 (例如,List<T>),因此群組會「具有一個」單一屬性形式的項目群組 (或數個屬性形式的多個項目群組)。 使用此模式時,您必須將 ItemsPath 設定為包含項目群組的屬性名稱。

下列範例說明「has-a-group」模式。 頁面類別具有名為 ViewModel (機器翻譯) 的屬性,會傳回檢視模型的執行個體。 CollectionViewSource (機器翻譯) 繫結至檢視模型的 Authors 屬性 (Authors 是群組物件的集合),同時指定其為包含分組項目的 Author.BookSkus 屬性。 最後,GridView (機器翻譯) 繫結至 CollectionViewSource,並且已定義其群組樣式,因此可以呈現在群組中的項目。

<Page.Resources>
    <CollectionViewSource
    x:Name="AuthorHasACollectionOfBookSku"
    Source="{x:Bind ViewModel.Authors}"
    IsSourceGrouped="true"
    ItemsPath="BookSkus"/>
</Page.Resources>
...
<GridView
ItemsSource="{x:Bind AuthorHasACollectionOfBookSku}" ...>
    <GridView.GroupStyle>
        <GroupStyle
            HeaderTemplate="{StaticResource AuthorGroupHeaderTemplateWide}" ... />
    </GridView.GroupStyle>
</GridView>

實作「is-a-group」模式的方式有兩種, 一種方式是撰寫您自己的群組類別。 您可以從 List<T> (「T」為項目類別) 衍生類別。 例如: public class Author : List<BookSku> 。 第二種方式是使用 LINQ 運算式,從 BookSku 項目的屬性值動態建立群組物件 (和群組類別)。 這種方法只會維護一般項目清單,並即時將項目分組,通常是從雲端服務存取資料的應用程式會採用的方法, 就好像可以彈性地依作者或內容類型將書籍分組,而不需要 AuthorGenre 等特殊群組類別。

下列範例說明使用 LINQ 的「is-a-group」模式。 這次我們依內容類型將書籍分組,並在群組標頭顯示內容類型名稱, 以參考群組 Key (機器翻譯) 值的「索引鍵」屬性路徑表示。

using System.Linq;
...
private IOrderedEnumerable<IGrouping<string, BookSku>> genres;

public IOrderedEnumerable<IGrouping<string, BookSku>> Genres
{
    get
    {
        if (this.genres == null)
        {
            this.genres = from book in this.bookSkus
                          group book by book.genre into grp
                          orderby grp.Key
                          select grp;
        }
        return this.genres;
    }
}

請記住,將 {x:Bind} (機器翻譯) 與資料範本一起使用時,我們需要藉由設定 x:DataType 值來指出繫結的類型。 如果是泛型,則無法在標記中表示,因此我們需要在群組樣式標頭範本中改用 {Binding} (機器翻譯)。

    <Grid.Resources>
        <CollectionViewSource x:Name="GenreIsACollectionOfBookSku"
        Source="{x:Bind Genres}"
        IsSourceGrouped="true"/>
    </Grid.Resources>
    <GridView ItemsSource="{x:Bind GenreIsACollectionOfBookSku}">
        <GridView.ItemTemplate x:DataType="local:BookTemplate">
            <DataTemplate>
                <TextBlock Text="{x:Bind Title}"/>
            </DataTemplate>
        </GridView.ItemTemplate>
        <GridView.GroupStyle>
            <GroupStyle>
                <GroupStyle.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Key}"/>
                    </DataTemplate>
                </GroupStyle.HeaderTemplate>
            </GroupStyle>
        </GridView.GroupStyle>
    </GridView>

SemanticZoom (機器翻譯) 控制項是讓使用者檢視及瀏覽分組資料的絕佳方式。 Bookstore2 範例應用程式會說明如何使用 SemanticZoom。 在該應用程式中,您可以檢視依作者分組的書籍清單 (放大檢視),也可以縮小以查看作者的捷徑清單 (縮小檢視)。 捷徑清單的瀏覽方式比捲動書籍清單更快。 放大和縮小檢視實際上是繫結至相同 CollectionViewSourceListViewGridView 控制項。

An illustration of a SemanticZoom

當您繫結至階層式資料時 (例如類別內的子類別),您可以選擇使用一系列項目控制項在 UI 中顯示階層式層級。 一個項目控制項中的選取項目會決定後續項目控制項的內容。 您可以將每個清單繫結至自己的 CollectionViewSource (機器翻譯),並將 CollectionViewSource 執行個體繫結在鏈結中,藉此讓清單保持同步, 這稱為主要/詳細資料 (或清單/詳細資料) 檢視。 如需詳細資訊,請參閱如何繫結至階層式資料並建立主要/詳細資料檢視

診斷和偵錯資料繫結問題

您的繫結標記包含屬性的名稱 (在 C# 中有時還包含欄位和方法), 因此,若您重新命名屬性,也必須變更參考該屬性的所有繫結。 忘記這麼做會造成典型的資料繫結錯誤範例,且您的應用程式將無法編譯或無法正確執行。

{x:Bind} (機器翻譯) 所建立的繫結物件與 {Binding} (機器翻譯) 基本上功能一樣, 但是 {x:Bind} 含有繫結來源的類型資訊,而且會在編譯階段產生原始程式碼。 若使用 {x:Bind},便可以執行與其餘程式碼相同的問題偵測作業, 包括繫結運算式的編譯階段驗證,以及透過在作為頁面部分類別產生的原始程式碼中設定中斷點,進行偵錯。 這些類別位於您 obj 資料夾中的檔案,名稱格式為 <view name>.g.cs (就 C# 而言)。 如果繫結發生問題,請在 Microsoft Visual Studio 偵錯工具中開啟 [發生未處理的例外狀況時中斷]。 偵錯工具會在中斷點中斷執行,然後開始偵錯。 {x:Bind} 所產生的程式碼會遵循繫結來源節點圖形中每個部分的相同模式,您可以使用 [呼叫堆疊] 視窗中的資訊,協助判斷造成問題的呼叫順序。

{Binding} (機器翻譯) 沒有繫結來源的類型資訊。 但在附加偵錯工具的情況下執行您的應用程式時,所有繫結錯誤都會顯示在 Visual Studio 的 [輸出] 視窗中。

在程式碼中建立繫結

注意 本節只適用於 {Binding} (機器翻譯),因為您無法在程式碼中建立 {x:Bind} (機器翻譯) 繫結。 不過,您可以使用 DependencyObject.RegisterPropertyChangedCallback (機器翻譯) 取得與 {x:Bind} 相同的部分優點,這可讓您在任何相依性屬性上註冊變更通知。

您也可以使用程序性程式碼 (而非 XAML) 將 UI 元素連結至資料。 若要這樣做,請建立新的 Binding (機器翻譯) 物件,設定適當的屬性,然後呼叫 FrameworkElement.SetBinding (機器翻譯) 或 BindingOperations.SetBinding (機器翻譯)。 當您想要在執行階段選擇繫結屬性值,或在多個控制項之間共用單一繫結時,以程式設計方式建立繫結會很有用。 不過請注意,呼叫 SetBinding 之後,您無法變更繫結屬性值。

以下範例示範如何在程式碼中實作繫結。

<TextBox x:Name="MyTextBox" Text="Text"/>
// Create an instance of the MyColors class 
// that implements INotifyPropertyChanged.
MyColors textcolor = new MyColors();

// Brush1 is set to be a SolidColorBrush with the value Red.
textcolor.Brush1 = new SolidColorBrush(Colors.Red);

// Set the DataContext of the TextBox MyTextBox.
MyTextBox.DataContext = textcolor;

// Create the binding and associate it with the text box.
Binding binding = new Binding() { Path = new PropertyPath("Brush1") };
MyTextBox.SetBinding(TextBox.ForegroundProperty, binding);
' Create an instance of the MyColors class 
' that implements INotifyPropertyChanged. 
Dim textcolor As New MyColors()

' Brush1 is set to be a SolidColorBrush with the value Red. 
textcolor.Brush1 = New SolidColorBrush(Colors.Red)

' Set the DataContext of the TextBox MyTextBox. 
MyTextBox.DataContext = textcolor

' Create the binding and associate it with the text box.
Dim binding As New Binding() With {.Path = New PropertyPath("Brush1")}
MyTextBox.SetBinding(TextBox.ForegroundProperty, binding)

{x:Bind} 與 {Binding} 的功能比較

功能 {x:Bind} 與 {Binding} 備註
Path 為預設屬性 {x:Bind a.b.c}
-
{Binding a.b.c}
Path 屬性 {x:Bind Path=a.b.c}
-
{Binding Path=a.b.c}
在 x:Bind 中,Path 的預設位置在 Page 的根目錄,而不是 DataContext。
索引編製程式 {x:Bind Groups[2].Title}
-
{Binding Groups[2].Title}
繫結至傳回集合中的指定項目。 僅支援以整數為基礎的索引。
附加屬性 {x:Bind Button22.(Grid.Row)}
-
{Binding Button22.(Grid.Row)}
附加屬性會使用括弧加以指定。 如果屬性未在 XAML 命名空間中宣告,請在它前面加上 xml 命名空間,該命名空間應該對應至文件前端的程式碼命名空間。
轉型 {x:Bind groups[0].(data:SampleDataGroup.Title)}
-
{Binding} 不需要。
轉換會使用括弧加以指定。 如果屬性未在 XAML 命名空間中宣告,請在它前面加上 xml 命名空間,該命名空間應該對應至文件前端的程式碼命名空間。
轉換器 {x:Bind IsShown, Converter={StaticResource BoolToVisibility}}
-
{Binding IsShown, Converter={StaticResource BoolToVisibility}}
轉換器必須於 Page/ResourceDictionary 的根目錄或 App.xaml 中宣告。
ConverterParameter、ConverterLanguage {x:Bind IsShown, Converter={StaticResource BoolToVisibility}, ConverterParameter=One, ConverterLanguage=fr-fr}
-
{Binding IsShown, Converter={StaticResource BoolToVisibility}, ConverterParameter=One, ConverterLanguage=fr-fr}
轉換器必須於 Page/ResourceDictionary 的根目錄或 App.xaml 中宣告。
TargetNullValue {x:Bind Name, TargetNullValue=0}
-
{Binding Name, TargetNullValue=0}
當繫結運算式的分葉為 Null 時使用。 針對字串值使用單引號。
FallbackValue {x:Bind Name, FallbackValue='empty'}
-
{Binding Name, FallbackValue='empty'}
當繫結路徑的任何部分 (分葉除外) 為 Null 時使用。
ElementName {x:Bind slider1.Value}
-
{Binding Value, ElementName=slider1}
使用 {x:Bind} 時,將繫結至欄位。Path 的預設位置在 Page 的根目錄,因此透過具名元素的欄位即可存取任何具名元素。
RelativeSource: Self <Rectangle x:Name="rect1" Width="200" Height="{x:Bind rect1.Width}" ... />
-
<Rectangle Width="200" Height="{Binding Width, RelativeSource={RelativeSource Self}}" ... />
使用 {x:Bind} 時,請為元素命名,並在 Path 中使用該名稱。
RelativeSource: TemplatedParent {x:Bind} 不需要
-
{Binding <path>, RelativeSource={RelativeSource TemplatedParent}}
使用 {x:Bind} ControlTemplate 上的 TargetType 表示繫結至父系範本。 針對 {Binding},一般範本繫結可以用在控制項範本中滿足大部分的用途。 但需要使用轉換器或雙向繫結時,請使用 TemplatedParent。<
來源 {x:Bind} 不需要
-
<ListView ItemsSource="{Binding Orders, Source={StaticResource MyData}}"/>
針對 {x:Bind},您可以直接使用已命名的元素,使用屬性或靜態路徑。
[模式] {x:Bind Name, Mode=OneWay}
-
{Binding Name, Mode=TwoWay}
Mode 可以是 OneTime、OneWay 或 TwoWay。 {x:Bind} 預設為 OneTime;{Binding} 預設為 OneWay。
UpdateSourceTrigger {x:Bind Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}
-
{Binding UpdateSourceTrigger=PropertyChanged}
UpdateSourceTrigger 可以是 Default、LostFocus 或 PropertyChanged。 {x:Bind} 不支援 UpdateSourceTrigger=Explicit。 {x:Bind} 一律針對所有案例使用 PropertyChanged 行為,但 TextBox.Text 除外,其會使用 LostFocus 行為。