Search code examples
c#wpfxaml

WPF: Address nested styles by key


I have a fairly complex WPF UserControl that needs a lot of custom styling, and several different styles for the same control types. The same styles are not used in any other places.

I would like to use nested styles (using Style.Resources) as a sort of namespacing mechanism as follows:

Example user control:

<UserControl Style="{StaticResource AwesomeControl}>
    <Grid>
        <Button Style="{StaticResource ButtonA}"/>
        <Button Style="{StaticResource ButtonB}"/>
    </Grid>
</UserControl>

How I want to define my styles:

<ResourceDictionary>
    <Style TargetType="UserControl" x:Key="AwesomeControl">
        <Style.Resources>
            <Style TargetType="Button" x:Key="ButtonA"> </Style>
            <Style TargetType="Button" x:Key="ButtonB"> </Style>
        </Style.Resources>
    </Style>
</ResourceDictionary>

However, this does not work. From what I can tell, it does not seem possible to address nested styles by their key. (I have searched around a lot, but cannot find a single example doing something like this.)

I can make it work easily by removing the nesting of styles, keeping them all at top level. However, then I have to change their keys to something like AwesomeControlButtonA, etc. to distinguish them from other parts of the application

That does not seem ideal to me.

So my question is:

Is something like I am trying with the code above possible? If not, are there other ways of namespacing I can use to prevent awkward keys like AwesomeControlButtonA?


Solution

  • Maybe DynamicResource could solve your problem

    <Grid>
        <Button Style="{DynamicResource ButtonA}"/>
        <Button Style="{DynamicResource ButtonB}"/>
    </Grid>
    

    In context:

    <Grid>
        <Grid.Resources>
            <Style x:Key="AW" TargetType="UserControl">
                <Style.Resources>
                    <Style TargetType="Button" x:Key="AB">
                        <Setter Property="Background" Value="Red" />
                    </Style>
                    <Style TargetType="Button" x:Key="BB">
                        <Setter Property="Background" Value="Yellow" />
                    </Style>
                </Style.Resources>
            </Style>
            <Style x:Key="AR" TargetType="UserControl">
                <Style.Resources>
                    <Style TargetType="Button" x:Key="AB">
                        <Setter Property="Background" Value="Green" />
                    </Style>
                    <Style TargetType="Button" x:Key="BB">
                        <Setter Property="Background" Value="Blue" />
                    </Style>
                </Style.Resources>
            </Style>
        </Grid.Resources>
    
        <StackPanel>
            <UserControl Style="{StaticResource AW}">
                <StackPanel>
                    <Button Content="A" Style="{DynamicResource AB}" />
                    <Button Content="A" Style="{DynamicResource BB}" />
                </StackPanel>
            </UserControl>
            <UserControl Style="{StaticResource AR}">
                <StackPanel>
                    <Button Content="A" Style="{DynamicResource AB}" />
                    <Button Content="A" Style="{DynamicResource BB}" />
                </StackPanel>
            </UserControl>
        </StackPanel>
    </Grid>
    

    enter image description here