WPF:建立 DataContext 的幾種寫法

整理幾種建立 DataContext 的寫法....

複習資料繫結的基礎觀念

所謂的資料繫結,就是把資料來源物件繫結至目標控制項。對應至實作,則是指定目標控制項的資料來源為何,以及來源物件的哪個屬性要連接至目標控制項的哪個屬性。繫結的模式又有單向、雙向、單次繫結、單向繫結至來源等分別,以應付不同的場合,例如資料來源如果是唯讀的,就只能採用單向繫結,也就是資料只會從資料來源流到目標控制項,而不會反其道而行。

由以上說明可以發現,資料繫結這個機制需要下列資訊方能運作:
  • 來源:資料來源物件及其屬性
  • 目標:目標控制項及屬性
  • 繫結模式
System.Windows.Data.Binding 類別即實作了上述概念。

底下是一個簡單的範例:

<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");
    }
}

延伸閱讀

沒有留言:

技術提供:Blogger.
回頂端⬆️