整理幾種建立 DataContext 的寫法....
複習資料繫結的基礎觀念
所謂的資料繫結,就是把資料來源物件繫結至目標控制項。對應至實作,則是指定目標控制項的資料來源為何,以及來源物件的哪個屬性要連接至目標控制項的哪個屬性。繫結的模式又有單向、雙向、單次繫結、單向繫結至來源等分別,以應付不同的場合,例如資料來源如果是唯讀的,就只能採用單向繫結,也就是資料只會從資料來源流到目標控制項,而不會反其道而行。
由以上說明可以發現,資料繫結這個機制需要下列資訊方能運作:
底下是一個簡單的範例:
結果:
此範例是使用 Source 屬性來指定控制項所欲繫結之資料來源。這種寫法有個缺點:如果有多個目標要繫結至同一個資料來源,就會寫一堆重複的程式碼,既不好看,也不利維護。
嗯,當一個資料來源需要繫結至多個目標控制項時,就很適合採用 DataContext。
使用 DataContext
顧名思義,DataContext 意味著「資料環境」,它有那麼一點點全域變數的味道,但只限於 UI 階層的共用--父層元素的 DataContext 可由子元素繼承並使用之。
底下幾個範例都是把 Label 控制項的 Content 屬性繫結至自訂的 Customer 物件的 CompanyName 屬性,所以先列出 Customer 類別的定義:
接著用幾張圖來說明在 XAML 中建立 DataContext 物件的幾種寫法。
範例 1:建立 Window 層級的 DataContext
你可以看到,在繫結資料時(步驟 2)並不需要特別指定 Label 控制項的 DataContext 屬性,這是因為 DataContext 會沿用上層(繼承父層)UI 元素所定義的 DataContext。也就是說,此範例的 Label 控制項在進行資料繫結時,會使用步驟 1 所建立的 DataContext 物件作為資料來源。
範例 2:把資料來源定義成資源
範例 3:繫結至控制項層級的 DataContext 物件
完整的 XAML 程式碼:
以上範例都是在 XAML 中建立資料來源物件(Customer)並指定控制項(或 Window) 的DataContext 屬性。這些動作當然也都可以用程式碼來完成,例如:
延伸閱讀
複習資料繫結的基礎觀念
所謂的資料繫結,就是把資料來源物件繫結至目標控制項。對應至實作,則是指定目標控制項的資料來源為何,以及來源物件的哪個屬性要連接至目標控制項的哪個屬性。繫結的模式又有單向、雙向、單次繫結、單向繫結至來源等分別,以應付不同的場合,例如資料來源如果是唯讀的,就只能採用單向繫結,也就是資料只會從資料來源流到目標控制項,而不會反其道而行。
由以上說明可以發現,資料繫結這個機制需要下列資訊方能運作:
- 來源:資料來源物件及其屬性
- 目標:目標控制項及屬性
- 繫結模式
底下是一個簡單的範例:
<Window x:Class="DataBindingBasics.HelloDataBinding" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:c="clr-namespace:System;assembly=mscorlib" Title="HelloDataBinding" Height="300" Width="300"> <Window.Resources> <c:String x:Key="str1">Hello</c:String> </Window.Resources> <Grid> <StackPanel> <TextBox Text="{Binding Source={StaticResource str1}, Mode=OneWay}" /> <TextBox Text="{Binding Path=Length, Source={StaticResource str1}, Mode=OneWay}"/> <TextBox DataContext="{StaticResource str1}" Text="{Binding Mode=OneWay}"> </TextBox> </StackPanel> </Grid> </Window>
結果:
此範例是使用 Source 屬性來指定控制項所欲繫結之資料來源。這種寫法有個缺點:如果有多個目標要繫結至同一個資料來源,就會寫一堆重複的程式碼,既不好看,也不利維護。
嗯,當一個資料來源需要繫結至多個目標控制項時,就很適合採用 DataContext。
使用 DataContext
顧名思義,DataContext 意味著「資料環境」,它有那麼一點點全域變數的味道,但只限於 UI 階層的共用--父層元素的 DataContext 可由子元素繼承並使用之。
底下幾個範例都是把 Label 控制項的 Content 屬性繫結至自訂的 Customer 物件的 CompanyName 屬性,所以先列出 Customer 類別的定義:
namespace DataContext101 { public class Customer { public string CompanyName { get; set; } } }
接著用幾張圖來說明在 XAML 中建立 DataContext 物件的幾種寫法。
範例 1:建立 Window 層級的 DataContext
你可以看到,在繫結資料時(步驟 2)並不需要特別指定 Label 控制項的 DataContext 屬性,這是因為 DataContext 會沿用上層(繼承父層)UI 元素所定義的 DataContext。也就是說,此範例的 Label 控制項在進行資料繫結時,會使用步驟 1 所建立的 DataContext 物件作為資料來源。
範例 2:把資料來源定義成資源
範例 3:繫結至控制項層級的 DataContext 物件
完整的 XAML 程式碼:
<Window x:Class="DataContext101.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:DataContext101" Title="MainWindow" Height="170" Width="525"> <Window.DataContext> <local:Customer CompanyName="MacroSoft" /> </Window.DataContext> <Window.Resources> <local:Customer x:Key="customerModel" CompanyName="IBeAm"> </local:Customer> </Window.Resources> <Grid> <StackPanel Orientation="Vertical"> <Label Content="{Binding Path=CompanyName}" /> <Label DataContext="{StaticResource customerModel}" Content="{Binding CompanyName}"/> <Label Content="{Binding Path=CompanyName}"> <Label.DataContext> <local:Customer CompanyName="Doodle" /> </Label.DataContext> </Label> </StackPanel> </Grid> </Window>
以上範例都是在 XAML 中建立資料來源物件(Customer)並指定控制項(或 Window) 的DataContext 屬性。這些動作當然也都可以用程式碼來完成,例如:
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); // 建立 Window 層級的 DataContext 物件. this.DataContext = new Customer() { CompanyName = "MacroSoft" }; // 設定特定控制項的 DataContext 和資料繫結. label1.DataContext = new Customer() { CompanyName = "Oracall" }; label1.SetBinding(Label.ContentProperty, "CompanyName"); } }
延伸閱讀
沒有留言: