3

Usingthe setup below, I can color the whole width of the window purplish. The inner stack panel is chartreusian and shifted to the left.

<StackPanel HorizontalAlignment="Stretch"
            Orientation="Horizontal"
            Background="BlueViolet"
            Height="70">
  <StackPanel HorizontalAlignment="Left"
              Orientation="Horizontal"
              Background="Chartreuse" >

I was expecting that if I changed the horizontal alignment of the inner stack panel to streched, it'd fill out all the width as well but that doesn't happen. I've tried both right and streched alignments and it seems that it's not affecting the width of the inner control.

According to the posts I've found that is the way to achieve it (and it certainly worked for the outer control). What can I be missing? I've removed the other controls declared in the outer panel (i.e. all the siblings to the chartreusily colored one) with no difference.

Konrad Viltersten
  • 36,151
  • 76
  • 250
  • 438
  • Just replace the outer `StackPanel` by a `Grid` – Flat Eric Aug 14 '15 at 08:54
  • @FlatEric Is there an alternative approach, as well? I'm using the stackiness of the panel when I add other components. I'm afraid that I'll affect other parts of the mark-up (which might not be apparent until later). Are you able to offer a suggestion as to **why** the stacky misbehaves, technically speaking? Also, at any rate, you should post your comment as a reply, probably a bit elaborated. – Konrad Viltersten Aug 14 '15 at 09:03

3 Answers3

4

A StackPanel will provide to its content as much space as required but also only as few as necessary.

If you want to fill exactly the width of the window, just replace the outer StackPanel by a Grid

If you want the StackPanel to fill at least the whole with, you can bind the MinWidth to its parent ActualWidth:

<StackPanel HorizontalAlignment="Stretch"
    Name="parent"
    Orientation="Horizontal"
    Background="BlueViolet"
    Height="70">

    <StackPanel HorizontalAlignment="Stretch"
        MinWidth="{Binding Path=ActualWidth, ElementName=parent}"
        Orientation="Horizontal"
        Background="Chartreuse" >
    </StackPanel>
</StackPanel>
Flat Eric
  • 7,971
  • 9
  • 36
  • 45
2

I spent a lot of time in the past struggling with stackpanels.

Here is what happens: Your outer stackpanel (#1) has horizontal orientation, what means, that it can fill as many childs as needed, stacking them horizontally. Whenever child is rendered, there is a dialog between child and parent:

--(Child) I want to render and I have this size. Can you provide me enought space?

--(Parent) I'll do calculations and we'll see how it goes.

In case of nested stackpanels your outer stackpanel tries to stretch and demands infinite width and it's parent grid gives him just all the width he has. But the purpose of stackpanel is to be infinite in one direction and if it's child asks for infinite width (what inner stackpanel does, when you set horizontal alignment to stretch) then we just give him minimum amount of width, since otherwise they would grow out of control and consume all memory on your PC.

So this is just an artistic view on what happens and it can be inaccurate.

Update:

Putting things simply: You can't set horizontal alignment to stretch for a child of a stackpanel with horizontal orientationand you can't set vertical alignment to stretch for a child of a stackpanel with vertical orientation. Well, you can, but it won't stretch, because if it could, then it would have stretched infinitely

Answer: Replace inner or outer stackpanel with a grid. The fact, that you are using 2 nested stackpanels with a same orientation says that you are doing something wrong. To be honest, the only application of stackpanel, in my opinion, is inside of a scrollviewer. In other cases it's better to use WrapPanel.

netaholic
  • 1,345
  • 10
  • 22
1

I too struggle with this and provide this solution incase someone else is looking for a similar solution.

My particular issue was I needed to get the Hamburger Menu to the top and out of the SplitView. I was then trying to get the stackpanel to fill out the whole region below. This works well and a screen shot below shows what it looks like.

Hope this helps and happy to be corrected if this is not best practise.

<Grid Background="{ThemeResource AppBarToggleButtonCheckedPointerOverBackgroundThemeBrush}">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <StackPanel Height="50" Grid.Row="0">
        <StackPanel Background="Gray" Height="50" HorizontalAlignment="Stretch">
            <Button x:Name="HamburgerButton" FontFamily="Segoe MDL2 Assets" Content="&#xE700;"
                Width="50" Height="50" Background="Transparent" Click="HamburgerButton_Click"/>
        </StackPanel>
    </StackPanel>
    <SplitView Grid.Row="1" x:Name="MySplitView" DisplayMode="Overlay"  IsPaneOpen="False" 
            CompactPaneLength="1" OpenPaneLength="150" VerticalAlignment="Stretch">
        <SplitView.Pane >
            <StackPanel >

            <StackPanel Orientation="Horizontal">
                    <Button x:Name="LogIn" FontFamily="Segoe MDL2 Assets" Content="&#xE825;" Width="50" Height="50" Background="Transparent"/>
                    <TextBlock Text="Log In" FontSize="18" VerticalAlignment="Center" />
             </StackPanel>

                <StackPanel Orientation="Horizontal">
                    <Button x:Name="SignUp" FontFamily="Segoe MDL2 Assets" Content="&#xE10F;" Width="50" Height="50" Background="Transparent"/>
                    <TextBlock Text="Sign Up" FontSize="18" VerticalAlignment="Center" />
                </StackPanel>
            </StackPanel>
        </SplitView.Pane>
        <SplitView.Content>
            <Grid VerticalAlignment="Stretch">
            </Grid>
        </SplitView.Content>
    </SplitView>    
</Grid>

Menu close:

enter image description here

Menu open:

enter image description here

timv
  • 3,346
  • 4
  • 34
  • 43