添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Suppose I have a WPF style for a container element such as a grid which applies styles to its child items automatically, like this:

<Window.Resources>
    <Style TargetType="Grid" x:Key="FormStyle">
        <Style.Resources>
            <Style TargetType="Label">
                <Setter Property="FontSize" Value="50"/>
            </Style>
        </Style.Resources>
    </Style>
</Window.Resources>

How can I then override certian elements of that style within the grid itself? For example suppose I wanted one grid to have FormStyle but also have a blue label, like this (which doesnt work):

<!-- this works fine and Label size = 50 -->
<Grid Style="{StaticResource FormStyle}">
    <Label Content="Blah"/>
</Grid>
<!-- But this doesnt, label is blue, but normal font size -->
<Grid Style="{StaticResource FormStyle}">
    <Grid.Resources>
        <Style TargetType="Label" BasedOn="{StaticResource {x:Type Label}}">
            <Setter Property="Foreground" Value="Blue"/>
        </Style>
    </Grid.Resources>
    <Label Content="Blah"/>
</Grid>

I am expecting the BasedOn={StaticResource {x:Type Label}} to refer to the current active style for Labels at the current scope - i.e. the label style within FormStyle. But it clearly doesnt and refers to the base outer label style.

If I do for instance this globally

<Style TargetType="Label">
    <Setter Property="FontSize" Value="50"/>
</Style>

Then it is all fine.

I could of course just name the styles, but surly there must be an easier/less verbose way?

Thanks

  • The lookup process checks for the requested key within the resource dictionary defined by the element that sets the property.

  • The lookup process then traverses the logical tree upward to the parent element and its resource dictionary. This process continues until the root element is reached.

  • App resources are checked. App resources are those resources within the resource dictionary that is defined by the Application object for your WPF app.

  • In your case to resolve BasedOn="{StaticResource {x:Type Label}}" WPF first looks in the ResourceDictionary defined inside of Grid, then in Window - the logical parent of the Grid - and it's Resources, and then finally in Application level resources. WPF will not find it anywhere - and defaults to the base style - due to the style being a nested style in FormStyle.

    Read further about Static Resource Lookup Behavior on Docs.

    To get the desired output, you could:

    1) Move your Label style out of FormStyle and in to Window.Resoruces

    2) Merge the Label style from FormStyle into the Label style defined in the Grid element.

    <Grid Style="{StaticResource FormStyle}">
        <Grid.Resources>
            <Style TargetType="Label">
                <Setter Property="Foreground" Value="Red"/>
                <Setter Property="FontSize" Value="50"/>
            </Style>
        </Grid.Resources>
        <Label Content="Blah"/>
    </Grid>
    

    3) Change your FormStyle not to have a nested style for Label, but to have setters for Label properties.

    <Window.Resources>
        <Style TargetType="Grid" x:Key="FormStyle">
            <Setter Property="Label.FontSize" Value="50"/>
        </Style>
    </Window.Resources>
                    Thanks very much very helpful.  Moving to Window/Grid sort of defeats the point as its intended to be an app level style used by several windows/controls (I failed to mention that in question).  Point 3 is great
    – James Hobson
                    Jan 30, 2020 at 7:21
            

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.