views:

1739

answers:

5

Given a StackPanel:

<StackPanel>
  <TextBox Height="30">Apple</TextBox>
  <TextBox Height="80">Banana</TextBox>
  <TextBox Height="120">Cherry</TextBox>
</StackPanel>

What's the best way to space out the child elements so that there are equally-sized gaps between them, even though the child elements themselves are of different sizes? Can it be done without setting properties on each of the individual children?

+1  A: 

If you use a UniformGrid control, you can obtain the same effect. This will automatically space out your controls both vertically and horizontally. See here for an example. Hope this helps!

Pwninstein
The cells in a UniformGrid are always the same size, so if the child elements were of different sizes then the gaps between them would be different, which isn't the effect I want. By "evenly space" I actually mean "space out so that there are equally-sized gaps between them" - I will update my question to clarify. Sorry!
GraemeF
This will make resizing look goofy
Paul Betts
+2  A: 

The UniformGrid might not be available in Silverlight, but someone has ported it from WPF. http://www.jeff.wilcox.name/2009/01/uniform-grid/

Jean Azzopardi
+15  A: 

Use Margin or Padding, applied to the scope within the container:

<StackPanel>
    <StackPanel.Resources>
        <Style TargetType="{x:Type TextBox}">
            <Setter Property="Margin" Value="0,10,0,0"/>
        </Style>
    </StackPanel.Resources> 
    <TextBox Text="Apple"/>
    <TextBox Text="Banana"/>
    <TextBox Text="Cherry"/>
</StackPanel>

EDIT: In case you would want to re-use the margin between two containers, you can convert the margin value to a resource in an outer scope, f.e.

<Window.Resources>
    <Thickness x:Key="tbMargin">0,10,0,0</Thickness>
</Window.Resources>

and then refer to this value in the inner scope

<StackPanel.Resources>
    <Style TargetType="{x:Type TextBox}">
        <Setter Property="Margin" Value="{StaticResource tbMargin}"/>
    </Style>
</StackPanel.Resources>
Sergey Aldoukhov
The scoped Style is an *awesome* way to do that - thanks for the tip!
Paul Betts
A: 

For what it's worth, I think this is a huge oversight in WPF/Silverlight that you can't apply a cell padding at the container level. But alas, it is what it is and you have to apply to to the children as Sergey said.

Josh Einstein
+1  A: 

+1 for Sergey's answer. And if you want to apply that to all your StackPanels you can do this:

<Style TargetType="{x:Type StackPanel}">
    <Style.Resources>
        <Style TargetType="{x:Type TextBox}">
            <Setter Property="Margin" Value="{StaticResource tbMargin}"/>
        </Style>
    </Style.Resources>
</Style>

But beware: if you define a style like this in your App.xaml (or another dictionary that is merged into the Application.Resources) it can override the default style of the control. For mostly lookless controls like the stackpanel it isn't a problem, but for textboxes etc you may stumble upon this problem, which luckily has some workarounds.

Andre Luus