Search code examples
wpfwpf-style

How to set the properties of the child control of Label


I would like to change the properties of the Border control that is a child of the default Label control. I have the following style and everything except the changes to the Border control are being shown in the UI

<Style x:Key="StandardLabel" TargetType="{x:Type Label}" BasedOn="{StaticResource {x:Type Label}}">
    <Setter Property="HorizontalAlignment" Value="Center" />
    <Setter Property="ContentStringFormat" Value="{}{0:0.000}"/>
    <Setter Property="Height" Value="25"/>
    <Setter Property="Margin" Value="0"/>
    <Style.Resources>
        <Style TargetType="{x:Type Border}" >
            <Setter Property="Padding" Value="3"/>
        </Style>
    </Style.Resources>
</Style>

I used this answer as the basis for what I am trying, but it does not seem to work for me. Any thoughts on what I am doing wrong?


Solution

  • If you've got the same default Label template as me, the Border has padding set via an attribute, which due to dependency property value precedence will override anything done in a style.

    <ControlTemplate TargetType="{x:Type Label}">
        <Border 
            BorderBrush="{TemplateBinding BorderBrush}" 
            BorderThickness="{TemplateBinding BorderThickness}"
            Background="{TemplateBinding Background}" 
            Padding="{TemplateBinding Padding}" 
            SnapsToDevicePixels="true"
            >
    

    However, look what value that attribute uses: Padding="{TemplateBinding Padding}"

    So it'll use whatever Padding its templated parent has. That's the Label. So this should do what you want:

    <Style x:Key="StandardLabel" TargetType="{x:Type Label}" BasedOn="{StaticResource {x:Type Label}}">
        <Setter Property="Padding" Value="3" />
    

    That will work for any property where the Border has a TemplateBinding to a property of the Label. Anything else (if Border had any useful properties not already accounted for), you could use your local implicit style method; I tested that with a copy of the default style, with the Background attribute removed from the Border in the template:

    <Style x:Key="LabelStyle1" TargetType="{x:Type Label}" BasedOn="{StaticResource {x:Type Label}}">
        <Style.Resources>
            <Style TargetType="Border">
                <Setter Property="Background" Value="LightSkyBlue" />
            </Style>
        </Style.Resources>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Label}">
                    <Border 
                        BorderBrush="{TemplateBinding BorderBrush}" 
                        BorderThickness="{TemplateBinding BorderThickness}" 
                        Padding="{TemplateBinding Padding}" 
                        SnapsToDevicePixels="true"
                        >