控件(包括 ListBox)根本不使用 DataContext 的值做任何事情。其目的是为数据绑定提供上下文。
假设您有一个ListBox“myList”和一个MyData“myData”。 MyData 类型具有 ObservableCollection<Person> 类型的属性“People”,而 Person 类型具有字符串属性“Forename”和“Surname”。
以下所有内容都是等效的:-
myList.ItemsSource = myData.People;
或
myList.DataContext = myData;
myList.SetBinding(ItemsControl.ItemsSourceProperty, new Binding("People"));
或
myList.DataContext = myData.People;
myList.SetBinding(ItemsControl.ItemsSourceProperty, new Binding());
通常,虽然绑定是在 Xaml 中配置的,并且 LayoutRoot 的 DataContext 被分配了数据对象:-
LayoutRoot.DataContext = myData;
您可能有以下 Xaml:-
<Grid x:Name="LayoutRoot">
<ListBox x:Name="myList" ItemsSource="{Binding People}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Forename}" Margin="2" />
<TextBlock Text="{Binding Surname}" Margin="2" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
您会在这里注意到几件事。根本没有分配“myList”的DataContext。在这种情况下,将遍历控件的祖先树,直到找到确实具有分配给 DataContext 属性的值的祖先。
此外,为每个Person 实例动态生成的每个ListBoxItem 都将Person 实例分配为其DataContext,这就是Forename 和Surname 绑定的工作方式。