> 技术文档 > WPF中的DataContext以及常见的绑定方式

WPF中的DataContext以及常见的绑定方式

我们一起来理解 WPF MVVM 绑定的一个核心概念。

DataContext 是什么?

简单来说,DataContext 是每个 WPF 控件都拥有的一个属性,它代表了该控件的\"默认数据源\"或\"数据上下文\"。

您可以把它想象成:

  1. 一个\"背包\":每个控件都背着一个背包(DataContext),背包里装着它需要显示和操作的数据。
  2. 一个\"视野\":控件通过它的 DataContext 来\"看\"到它要绑定的数据对象。
  3. 一个继承属性:如果一个控件没有显式设置自己的 DataContext,它会自动继承其父控件的 DataContext。

在您提供的绑定中的具体含义

让我们分解这句绑定:
ItemsSource=\"{Binding Path=DataContext.HoleTypes, RelativeSource={...}}\"

这个绑定语句是在说:

Path=DataContext.HoleTypes”:我要绑定的路径,首先是对象的 DataContext 属性,然后是 DataContext 对象里面的 HoleTypes 属性。

但这里的 DataContext 指的是谁的 DataContext

这就是 RelativeSource 部分的作用了:
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}

这指明了:去找到最近的 DataGrid 类型的祖先元素,然后使用 它的 DataContext

所以,整句绑定的完整解读是:

“向上找到最近的 DataGrid 父控件,然后获取这个 DataGrid 的 DataContext 对象,再从这个 DataContext 对象中找到它的 HoleTypes 属性,并将这个属性作为我的 ItemsSource(数据项来源)。”


一个具体的例子

假设您的页面结构是这样的,并且设置了 DataContext:

// 在后台代码或 ViewModel 中public class MyViewModel{ public ObservableCollection<HoleType> HoleTypes { get; set; } // 这就是要绑定的数据 // ... 其他属性和方法 ...}// 在窗口的构造函数中public MainWindow(){ InitializeComponent(); this.DataContext = new MyViewModel(); // 窗口的 DataContext 被设置为 ViewModel}
<Window x:Class=\"YourApp.MainWindow\" DataContext=\"{Binding}\">  <Grid> <DataGrid x:Name=\"MyDataGrid\">  <DataGrid.Columns> <DataGridTemplateColumn>  <DataGridTemplateColumn.CellTemplate> <DataTemplate>  <ComboBox  ItemsSource=\"{Binding Path=DataContext.HoleTypes, RelativeSource={RelativeSource Mode=FindAncestor,  AncestorType={x:Type DataGrid}}}\"/>  </DataTemplate>  </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> </Grid></Window>

总结

场景 DataContext 的含义 一般绑定 {Binding Name} 使用当前控件自己的 DataContext 中的 Name 属性。 您的绑定 {Binding DataContext.X, RelativeSource=...} DataContext 在这里是一个属性路径的一部分。它指的是通过 RelativeSource 找到的那个祖先元素(如DataGrid) 所拥有的 DataContext 对象。然后再从这个对象中找 X 属性。

这种技巧在 DataTemplateControlTemplate用户控件内部极其常用,因为这些地方的本地 DataContext 发生了变化,需要\"回溯\"到外层的上下文来获取数据。