views:

153

answers:

2

I have created my own ControlTemplate for Button, like this:

<Style x:Key="LightButtonStyle" TargetType="{x:Type ButtonBase}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ButtonBase}">
                <Border
                    x:Name="WrappingBorder"
                    Margin="{TemplateBinding Margin}"
                    ...
                    >
                    <ContentPresenter 
                        Content="{TemplateBinding Content}" 
                        ...
                        >
                    </ContentPresenter>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Now, I have noticed that when I set margin to my button, like:

<Button 
    Style="{StaticResource LightButtonStyle}"
    Margin="20"
    >
    Hello world!
</Button>

the button has actually double Margin - 40. I assumed that the control should, in fact, never use Margin, and that Margin property is read only by button's ancestors during arrange phase. I have looked then into WPF default styles, and found out that no one of those used Margin.

Is this the right conclusion (that Margin is in control only to be correctly arranged by containers)? In other words, every time I use {TemplateBinding Margin} in my style, I'll get double margins instead? And is there some list of similar properties that my control shouldn't use (as they are meant only for 'surrounding world' only)?

Would you point me to MSDN page that explains this? Thank you!

EDIT:

I guess I should find answers in http://msdn.microsoft.com/en-us/library/ms745058.aspx and http://msdn.microsoft.com/en-us/library/ms751709.aspx, but I don't think they mentioned explicitly that it's never the control who uses the Margin property, that it is always the ancestor or wpf system who evalues it and uses it to affect the layout...

+1  A: 

Your conclusion is right, if you look at the framework provided default templates you'll see that the Margin inside the template is bound to the Padding property of the control.

Aviad P.
Thanks, I noticed this... Do you know about some msdn page or blogpost that would explain the role of Margin (and maybe other layout-specific properties) in layouting? I tried to google it, but came up with no real answer.
Tomáš Kafka
I'm sure google can help you, but I'll say (or rather, write) one thing. Margin is used by the container in the arrange pass of the layout process, the container will place the child element at a position that's derived from its horizontal and vertical alignments and its margin.
Aviad P.
Thank you, that's exactly what I wanted - that I except Margin, I should also never use s HorizontalAlignment and VerticalAlignment inside template.
Tomáš Kafka
+1  A: 

Margin is applied automatically by the layout system, inside a control template you should use Padding instead.

<Border x:Name="WrappingBorder" Margin="{TemplateBinding Padding}" ... />
Bryan Anderson
Aviad replied first (and hinted the phase when the margin is applied in a later comment), so I accepted his answer - but thank you very much as well!
Tomáš Kafka