DataContext属性是绑定的默认源,除非你像我们再上一章节做的那样,使用ElementName属性单独声明了其他源。这个属性定义在FrameworkElement类中,这是包括WPF Window在内的大多数UI控件的基类。简单来说,它允许你指定绑定的源。
起始时默认DataContext 都是null. DataContext是可以通过层次关系继承下去的 . 只要Window 被设置了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,就是告诉window我们把自己作为数据源.
在XAML中,我们会把各种信息绑定到Window的多种属性上,比如Title/Width/Height. 一旦为window指定了DataContext, 我们可以在所有的子控件上向全局变量一样使用它,不用一个个的绑定.
尝试运行一下这个例子并缩放窗口,你会看到窗口大小的缩放会即时反映在文本框中。你也可以尝试在第一个文本框中输入其他标题,但你会惊奇地发现这个变化不会即时反映在窗口上。相反,你需要将焦点移至其他控件后更改才会生效。这是为什么呢?这就是下一章节的主题了。
使用DataContext属性是在控件层次结构中设置所有绑定的基础。 这为您节省了为手动定义每个绑定源的麻烦,一旦您真正开始使用数据绑定,您就会体验到这个好处。
但是,这并不意味着您必须对Window中的所有控件使用相同的DataContext。 由于每个控件都有自己的DataContext属性,因此您可以轻松地破坏继承链并使用新值覆盖DataContext。 这允许你做一些事情,比如在窗口上有一个全局DataContext,然后在一个Panel上指定一个特定的DataContext上,这个Panel所有的子都使用这个特定的DataContext。