Let say you have 2 WPF buttons. One uses TextBlock, not the other one.
<Button x:Name="Button1">
<TextBlock>inside textblock</TextBlock>
</Button>
and
<Button x:Name="Button2">
no textblock
</Button>
Both buttons use this template which sets the "Foreground" dependency property to white:
<ControlTemplate x:Key="ButtonTemplate" TargetType="{x:Type Button}">
<Border Name="Border" TextElement.Foreground="White">
<ContentPresenter/>
</ControlTemplate>
The button wit开发者_Go百科h TextBlock has black text. The other one works fine. Why?
This is a matter of value inheritance as H.B. points out. Property value inheritance generally follows the logical tree.
In the first case:
<Button x:Name="Button1">
<TextBlock>inside textblock</TextBlock>
</Button>
The TextBlock's logical parent is the Button, so it will inherit it's value from Button and so on up the logical tree. So in the following code, the TextBlock will be red:
<Button x:Name="Button1" TextBlock.Foreground="Red">
<TextBlock>inside textblock</TextBlock>
</Button>
In the second case:
<Button x:Name="Button2">
no textblock
</Button>
A TextBlock is ultimately created by the ContentPresenter (see the ContentPresenter.ChooseTemplate method in ILSpy/Reflector). In this case, the TextBlock's logical parent is the ContentPresenter. So it will inherit it's value from ContentPresenter and so on up the logical tree, to the Border which has the White foreground defined.
This is documented briefly here.
Cannot find a relevant reference for this, if you have a TextBlock that comes with its own styles and settings which may override the attached property you set outside.
Edit: Possibly an issue of value inheritance and precedence in general.
If you have an implicit TextBlock style with colour in it then it won't pick the Foreground colour up, unless you explicitly do a template binding.
精彩评论