今天在学习刘铁锰老师的《深入浅出WPF》时看到一个非常感兴趣的知识点,虽然最近的工作没有使用过,不够我还是想在我的博客了做个记录,一来可以时常回顾,二来为以后工作多积累个解决问题的方法。
有时候我们不能确定Binding的Source的对象叫什么名字,但是知道它作为Binding目标的对象在UI布局上有相对关系,比如控件自己关联自己的某个数据,关联自己某级容器的数据。这时候我们就要使用Binding的RelativeSource属性。
RelativeSource属性的数据类型为RelativeSource类,通过这个类的几个静态或非静态属性我们可以控制它搜索相对数据源的方式。举个例子,下面我写的代码是多层布局控件内放置着一个TextBox,为了区分各个布局控件让结果更加清晰明了我还在每个控件中添加了Border。
<Grid Height="300" Width="300" x:Name="GridFirst">
<Border BorderThickness="30" BorderBrush="Black" x:Name="BorderFirst">
<DockPanel x:Name="DockPlaneFirst">
<Border BorderThickness="30" BorderBrush="Yellow" x:Name="BorderSed">
<Grid x:Name="GridSed">
<Border BorderThickness="30" BorderBrush="Pink" x:Name="BorderThird">
<DockPanel x:Name="DockPlaneSed">
<Border BorderThickness="30" BorderBrush="Bisque" x:Name="BorderFourth">
<TextBox Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Grid},AncestorLevel=1},Path=Name}"
Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Border},AncestorLevel=2},Path=BorderBrush}" ></TextBox>
</Border>
</DockPanel>
</Border>
</Grid>
</Border>
</DockPanel>
</Border>
</Grid>
AncestorType属性告诉Binding寻找那个类型的对象作为自己的源,不是这个类型的对象会被跳过。
AncestorLevel属性指的是以Binding目标控件(也就是上面代码中的TextBox)为起点的层级偏移量——BorderFourth的偏移量为1,DockPlaneSed的偏移量为2,以此类推。
Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Grid},AncestorLevel=1},Path=Name}"
Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Border},AncestorLevel=2},Path=BorderBrush}"
这两段代码的意思是告诉Binding从自己的第一层一次向外找,找到第一个Grid,将其Name属性与自己的Text相绑定,找到第二个Border,将其BorderBrush属性与自己的Background属性相绑定
运行结果如下