Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
799 views
in Technique[技术] by (71.8m points)

wpf - Set Style for all elements inside ContentPresenter

I overrided the template of wpf expander. The header has ContentPresenter

<ContentPresenter x:Name="HeaderContent"
                  Grid.Column="1"
                  Margin="0,0,4,0"
                  HorizontalAlignment="Left"
                  VerticalAlignment="Center"
                  RecognizesAccessKey="True"
                  SnapsToDevicePixels="True"
                  >
    <ContentPresenter.Resources>
        <Style BasedOn="{StaticResource Expanderheader-Naming}" 
               TargetType="{x:Type TextBlock}" />
     </ContentPresenter.Resources>
</ContentPresenter>

Where I tried to add my style for all TextBlocks inside. My style works if I set the header as a property:

<Expander Header="HelloWorld">

But it doesn't when I try to set it in the other manner.

<Expander>
    <Expander.Header>
        <Grid x:Name="MyGrid">
            <TextBlock>Hello Man</TextBlock>
        </Grid>  
    </Expander.Header>
</Expander>

How to set this style for any TextBlocks inside the ContentPresenter?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You ran into typical style inheritance issue in wpf.

A control looks for its style at the point when it is being initalized. The way the controls look for their style is by moving upwards in logical tree and asking the logical parent if there is appropriate style for them stored in parent's resources dictionary.

To explain to you what you doing wrong in your example lets think like this.

In first example the header properly is just storing "HelloWorld" and later when control is being initalized "HelloWorld" will be injected into ContentPresenter. This approach provides "HelloWorld" with ContentPresenter being it logical parent and so the style is applied properly since the style can be found.

In second example you create a Grid and inside that Grid you have a TextBlock.

At point of control initalization the logical parent of your TextBlock is Grid and futhermore Grid's logical parent is Expander itself. When looking for style for TextBlock the WPF will ask TextBlock's logical parent if it has a proper style in its resources for the TextBlock and the answer will be NO. There is no proper style for the TextBlock inside Grid.Resources and there is no proper style for the TextBlock inside Expander.Resources.

The proper style would be inside ContentPresenter just in this case the ContentPresenter is not part of logical tree.

That is how you lose the style in your second example.

In order to fix this I suggest you to stick to first example or to change where the style is being stored to. Usually all styles shall be stored inside Window.Resources.

EDIT 2 Take a look at this example carefully:

<Window.Resources>
    <Style x:Key="textBlockStyle" TargetType="TextBlock">
        <Setter Property="Background" Value="Blue"/>
    </Style>


    <Style TargetType="Button">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <ContentPresenter>
                        <ContentPresenter.Resources>
                            <Style TargetType="TextBlock" BasedOn="{StaticResource textBlockStyle}"/>
                        </ContentPresenter.Resources>
                    </ContentPresenter>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
<StackPanel>
    <Button Content="Yay, it worked!" />
    <Button>
        <Grid>
            <TextBox Text="It doesn't work this way!"/>
        </Grid>
    </Button>
    <Button>
        <Grid>
            <Grid.Resources>
                <Style TargetType="TextBlock" BasedOn="{StaticResource textBlockStyle}"></Style>
            </Grid.Resources>
            <TextBlock Text="Yay it works again! Woop Woop"/>
        </Grid>
    </Button>
</StackPanel>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.8k users

...