Fill StackPanel inside DockPanel - c#

This should be easy: how can I stretch StackPanel inside the DockPanel, so that it would fill the whole parent's content and also maintain it's HorizontalAlignment?
Example:
<DockPanel LastChildFill="True">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Background="Yellow">
<Button Height="30">Button1</Button>
<Button Height="30">Button2</Button>
</StackPanel>
</DockPanel>
In this example the StackPanel's width is the same as the combined width from both buttons (and the background here is yellow), but the remaining space in DockPanel stays white. Looks like the LastChildFille property isn't working in my example.

I think by setting HorizontalAligment to Center on the StackPanel you are overriding the behavior of the DockPanel to fill the whole space with the StackPanel.
When i understand your question right, you want that the full space is yellow and the stackpanel with buttons is centered in the middle. Then you should wrap the StackPanel inside a Grid.
<DockPanel LastChildFill="True">
<Grid Background="Yellow">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button Height="30">Button1</Button>
<Button Height="30">Button2</Button>
</StackPanel>
</Grid>
</DockPanel>

Related

WPF UserControls display left when I specify HorizontalAlignment="Right"

This is my WPF UserControl code reduced to the relevant part:
<UserControl x:Class="AKPS.View.UserCalibWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Width="1600" >
<Button Height="45" Width="100" />
<Button Height="45" Width="100" />
</StackPanel>
Why do the 2 buttons display on the left?
You are having a Width for your StackPanel removing that will align your stack panel to right with your controls in it.
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
<Button Height="45" Width="100" />
<Button Height="45" Width="100" />
</StackPanel>
A StackPanel does exactly that - it stacks elements together, in your case, horizontally. Your HorizontalAlignment is referring to the stack panel, which will shift it to the right, not the buttons inside them.
Instead, perhaps try using a Grid instead of a StackPanel, and then placing your StackPanel (with no Width element set) inside it.
HorizontalAlignment controls the container's alignment.
Try HorizontalContentAlignment instead.
As Abin indicated, in my haste I'd forgotten StackPanel doesn't have a HorizontalContentAlignment property.
You could achieve similar functionality with a DockPanel though, or use Abin's solution.

WPF ScrollViewer is not working

I want to add scroll view to my program and I tried ScrollView control but that don't take effect. It's my first time dealing with scrolls please help me :).
My xaml Code:
<DockPanel Grid.Row="1" Background="#FF695887">
<ScrollViewer VerticalScrollBarVisibility="Auto" Height="795">
<Canvas Name="zemelapis" Height="Auto" Width="Auto">
<Image Name="pav_kelias" />
<Image Name="car1" />
</Canvas>
</ScrollViewer>
</DockPanel>
Because these 2 images is not fitting here I need a scroll for them. Maybe I should use ScrollBar?
My program example: https://gyazo.com/a4ba7e4d5004632e2229a87e686c4c09
, as you can see bottom image is not fitting in range of window.
You have specified Auto as Height and Width. This implies that the Canvas will fill the height available to it.
From the documentation:
Auto sizing behavior implies that the element will fill the height
available to it.
In this case the available height is the height of the ScrollViewer.
If you want the Canvas to be bigger, and hence the ScrollViewer to scroll, you should set a height on Canvas that is bigger than the height of ScrollViewer.
So, for example:
<DockPanel Grid.Row="1" Background="#FF695887">
<ScrollViewer VerticalScrollBarVisibility="Auto" Height="795">
<Canvas Name="zemelapis" Height="1000" Width="Auto">
<Image Name="pav_kelias" />
<Image Name="car1" />
</Canvas>
</ScrollViewer>
</DockPanel>
If you want your ScrollViewer to work easily, use a Grid instead of a Canvas:
<DockPanel Background="#FF695887">
<ScrollViewer >
<Grid Name="zemelapis">
<Image Name="pav_kelias" Source="acteurs.png"/>
<Image Name="car1" Source="public.jpg"/>
</Grid>
</ScrollViewer>
</DockPanel>
As explain by Domysee, Canvas gives you total control of the layout. Grid however will automatically adjust its size depending on the content.
See http://www.wpf-tutorial.com/panels/introduction-to-wpf-panels/

Not able to stretch an inner StackPanel

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.
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>
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.
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=""
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="" 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="" 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:
Menu open:

ScrollBar Disabled

I was trying to implement a ScrollViewer like so;
<Height="auto" Width="auto"
MaxHeight="500" MaxWidth="400"
ResizeMode="NoResize" WindowStyle="None">
<Grid>
<StackPanel>
<ScrollViewer Name="scrlBr">
<StackPanel Orientation="Vertical">
<TextBlock Name ="txtBlock" Margin="10" Height="auto"
Width="auto" TextWrapping="Wrap"></TextBlock>
<Button Name="btnOk" Click="btnOk_Click" Width="80"
HorizontalAlignment="Center">Close!</Button>
</StackPanel>
</ScrollViewer>
<Label HorizontalAlignment="Center" FontSize="3"
Name="lblScrollDown">\/</Label>
</StackPanel>
</Grid>
</Window>
The problem I'm having is that the scroll bar appears disabled, while the text obviously goes down off the window and I can't see the btnOk. Surely if the window has a fixed height and the TextBlock and Button, which are contained in the Scrollviewer, are bigger than the window then the ScrollBar should be enabled, no?
UPDATE
I worked out that the problem lies in having the ScrollViewer within a StackPanel. Might try it with a Grid instead... Update to come.
SOLUTION
I was right about the Stackpanel being the problem and went with Heinzi's suggestion of using the DockPanel and all's workin' fine. :) Thanks!
The problem is your StackPanel. It always takes all the vertical space it needs, so the container of the ScrollPanel is much larger than the window itself, and the ScrollViewer sees no need to scroll.
Solution: Replace the StackPanel with a DockPanel. Move the <Label> declaration to the top and dock it to the bottom of the DockPanel. The last child in a DockPanel (which is the ScrollViewer in this case) always fills the remaining space:
<Grid>
<DockPanel>
<Label DockPanel.Dock="Bottom" ... Name="lblScrollDown">\/</Label>
<ScrollViewer Name="scrlBr">
...
</ScrollViewer>
</DockPanel>
</Grid>
Try setting the CanContentScroll property on True from the ScrollViewer and set a fixed height of the StackPanel, as a StackPanel is designed to grow indefinitely in one direction. Or better, use a different panel to stack your items in.
Maybe you need write something like this
<ScrollViewer Name="scrlBr" VerticalScrollBarVisibility="auto" HorizontalScrollBarVisibility="auto">
...
</ScrollViewer>

WPF Create a slide out panel

I don't know how this works technically but my requirement is as follows. I have a DataGrid and to input data into the DataGrid, I want a panel at the bottom of the DataGrid that slides out on a button click showing input options. Except, as the panel slides out, the DataGrid has to resize vertically as well. Can someone throw some light on how I can implement this?
You should be able to use a StackPanel with 2 children, your grid and your panel. Set the initial height of your panel to 0. Once the button is clicked, set the height to whatever you need it to be (e.g., MyPanel.Height = 20). You might want to wrap the grid in a ScrollViewer in case that is needed.
<StackPanel Orientation="Vertical">
<ScrollViewer Height="Auto" VerticalAlignment="Stretch">
<Grid Height="*" VerticalAlignment="Stretch" />
</ScrollViewer>
<ContentControl x:Name="MyPanel" Height="0" />
</StackPanel>
You might need to experiment with VerticalAlignment and Height="Auto" or Height="0" to get the layout you want.
You can use Expander. Please look at the following code snippet.
<DockPanel>
<Expander DockPanel.Dock="Bottom">
<StackPanel>
<TextBlock Height="25"></TextBlock>
<TextBlock Height="25"></TextBlock>
<TextBlock Height="25"></TextBlock>
</StackPanel>
</Expander>
<Border BorderBrush="LightGreen" BorderThickness="2">
<DataGrid/>
</Border>
</DockPanel >

Categories