DataContext屬性是綁定的默認源,除非你具體指定了另外一個源,就像上一章裏面我們使用了ElementName屬性。它由FrameworkElement類定義,大部分UI控件包括WPF窗口都繼承於此類。簡單地說,它允許你指定一個綁定的基。
DateContext並沒有默認源(剛開始的時候是NULL),但是它貫穿整個空間層次結構,你可以爲窗口設置一個DataContext,然後在任意的子控件裏面使用它。讓我們用代碼來舉例說明:
<Window x:Class="WpfTutorialSamples.DataBinding.DataContextSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DataContextSample" Height="130" Width="280">
<StackPanel Margin="15">
<WrapPanel>
<TextBlock Text="Window title: " />
<TextBox Text="{Binding Title, UpdateSourceTrigger=PropertyChanged}" Width="150" />
</WrapPanel>
<WrapPanel Margin="0,10,0,0">
<TextBlock Text="Window dimensions: " />
<TextBox Text="{Binding Width}" Width="50" />
<TextBlock Text=" x " />
<TextBox Text="{Binding Height}" Width="50" />
</WrapPanel>
</StackPanel>
</Window>
using System;
using System.Windows;
namespace WpfTutorialSamples.DataBinding
{
public partial class DataContextSample : Window
{
public DataContextSample()
{
InitializeComponent();
this.DataContext = this;
}
}
}
後臺代碼只添加了一行有意思的代碼:在標準InitalizeComponent()調用之後,我們將“this”賦值給DataContext,這將告訴窗口我們系統窗口本身作爲數據上下文。
在XAML中,我們綁定了窗口的一些屬性值,如Title,Width和Height。由於窗口有一個DataContext,它可以傳遞給子控件,我們不再需要給每一個綁定定義一個源。如果這些屬性是全局變量,直接使用它們的值就行。
運行上面的代碼,然後改變窗口大小,你會發現高和寬的值會立馬改變。如果編寫一個不同的標題在第一個文本框裏,你會發現標題並沒有立即被改變。相反地,你必須將光標移動到其他控件上改變纔會生效。爲什麼會這樣?這是下一章的主題。(注:我在VS2012裏面試這個例子,標題是立即實時改變的)
總結
使用DataContext屬性就好像設置了所有綁定的基礎,能夠貫穿整個控件層次。這樣就節省了手動爲每一個綁定定義源,一旦你真正開始使用數據綁定,肯定會感激如此節省的時間。
但是,這並不意味着你必須在一個窗口裏面爲所有控件使用同樣的DataContext。由於每一個控件都有其自己的DataContext屬性,你可以很容易的打破繼承鏈,用新值來重寫DataContext。這就允許你在窗口裏使用一個全局DataContext,然後在像panel這樣的地方使用本地具體的DataContext,以一種獨立的格式或者像上面的列出的那樣。