DataContext属性:
上文中我们使用DataContext作为Binding源写了案例代码。地址:@L_403_0@
当时是实现了另外一个代码,但是遇到问题,先贴出来代码,然后附一下原因:
遇到的问题:
namespace DataBindingExample { /// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window1 : Window { PersonName superStarName; PersonAge superStarAge; public Window1() { superStarName = new PersonName() { Name = "LeBron James" }; superStarAge = new PersonAge() { Age = 29 }; InitializeComponent(); this.grid1.DataContext = superStarAge; this.stackPanel1.DataContext = superStarName; } } public class PersonName : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private string name; public string Name { get { return name; } set { name = value; if (this.PropertyChanged != null) { this.PropertyChanged.Invoke(this,new PropertyChangedEventArgs("Name")); } } } } public class PersonAge : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private int age; public int Age { get { return age; } set { age = value; if (this.PropertyChanged != null)//激发事件,参数为Age属性 { this.PropertyChanged.Invoke(this,new PropertyChangedEventArgs("Age")); } } } } }xaml代码如下:
<Grid x:Name="grid1"> <StackPanel x:Name="stackPanel1"> <TextBox FontWeight="Bold" Height="25" Margin="5" x:Name="textBox2" Text="{Binding Path = Age,Mode = OneWay}"/> <TextBox FontWeight="Bold" Height="25" Margin="5" x:Name="textBox1" Text="{Binding Path = Name,Mode = OneWay}"/> </StackPanel> </Grid>当时是分别为外层的grid和stackpanel分别赋予了DataContext。则UI树的结构是这个样子。
我们已经知道,当没有Source的时候,Binding会自动沿着UI元素树的上层寻找满足Path的DataContext。所以会认为,两个TextBox都会显示出来,一个显示名字,一个显示Age。实际的结果是:
可以看出来,age 没有显示出来,不是自动在UI树上寻找的吗?为什么在Grid中的DataContext 不起作用呢。下面写出原因:
原因:
"数据上下文"是这样一个概念,它允许对象从它们在对象树中的父级来继承绑定指定信息。它其实是一个依赖属性。依赖属性的一个很重要的特点是当你没有为控件中的某个依赖属性显示赋值的时候,控件会把自己容易的属性值借过来当作自己的属性。实际上属性值沿着UI树往下传递了。而我们上文也提到了。DataContext这个属性是FrameworkElement的基本属性,在每个控件中都存在。而我们两个TextBox都没有明确的赋值。所以它们两个都会借它们容器的DataContext值,也就是StackPanel的值,即 superStarName。我们这里可以弹出个MessageBox来看一下。
可以看出来,两个都是PersonName。So 问题解决。
Binding沿着UI元素树向上找只是给我们的错觉。实际上不是这个样子的。
结论:
1) 当UI的多个控件都使用Binding 关注同一个对象的时候,不妨使用DataContext,关注的不是一个的时候,不建议使用。
2)DataContext就相当于数据的"制高点",只要把数据放上去,其他元素都可以看到。(通过以依赖属性的特性)