Search code examples
wpfstylesgroupbox

using style in WPF


In my application I use the ShinyBlue.xaml resource dictionary which has this code for the GroupBox control:

    <Style TargetType="{x:Type GroupBox}">

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type GroupBox}">
                <Grid SnapsToDevicePixels="true">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="6" />
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="6" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="*" />
                        <RowDefinition Height="6" />
                    </Grid.RowDefinitions>
                    <Border Grid.ColumnSpan="4" Grid.RowSpan="4"
                            Background="{DynamicResource LightBrush}"
                            CornerRadius="4,4,4,4"
                            BorderThickness="1,1,1,1" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>

   </Style>

These style common for all app. But in one of the forms I want to change the Background to Transparent. I want override only the Background property but it doesn't work

<Style TargetType="GroupBox" BasedOn="{StaticResource {x:Type GroupBox}}">
    <Setter Property="Background" Value="Transparent"/>
</Style>

The code above does not work properly.

How can I change the GroupBox Background in a specific form ?.


Solution

  • Your ControlTemplate does not actually use the Background property, but it assigns a concrete value to the Border's Background property, namely {DynamicResource LightBrush}. Now, when you set the Background property locally, this has no effect because the Border still uses the LightBrush resource.
    You have to use TemplateBindings to make the correct Background appear in your control like this:

    <Style TargetType="{x:Type GroupBox}">
        <!-- set default value for the template -->
        <Setter Property="Background" Value="{DynamicResource LightBrush}" />
    
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type GroupBox}">
                    <Grid SnapsToDevicePixels="true">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="6" />
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="6" />
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="*" />
                            <RowDefinition Height="6" />
                        </Grid.RowDefinitions>
                        <!-- Note the new TemplateBinding for the Background property! -->
                        <Border Grid.ColumnSpan="4" Grid.RowSpan="4" Background="{TemplateBinding Background}" CornerRadius="4,4,4,4" BorderThickness="1,1,1,1" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    
    </Style>
    

    This way, the Border actually uses the GroupBox's Background property. To make it use the LightBrush by default, I have added a Setter which defines the default value for the Background property. This value can then be overridden by locally setting the Background property on your GroupBox.