Aligning controls on both left and right side in a stack panel in WPF
Solution 1
Just do not use a StackPanel
, StackPanels
stack. They do, for obvious reasons, not allow alignment in the direction in which they stack. Use a Grid
, with column definitions like so:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
Solution 2
Even though this is old, should someone come across this like I did, here's a simple solution.
Make a new grid and inside that grid put two stack panels with different Horizontal Alignment.
<Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<!--Code here-->
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<!--Code here-->
</StackPanel>
</Grid>
The possible issue is that now without extra handling the two could overlap with each other.
Solution 3
As you have set the StackPanel
's orientation to Horizontal
, the HorizontalAlignment
property won't work on child-elements. You can keep the StackPanel
if you need additional controls, though I would recommend switching to a Grid
(among other things) to build the layout you want.
Also, the Grid
will allow you to control the actual width of each column:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="150" />
</Grid.ColumnDefinitions>
<RadioButton
Grid.Column="0"
...
/>
<Label
Grid.Column="1"
...
/>
</Grid>
Solution 4
User @pasx is right. You should use DockPanel and dock the RadioButton to the left side, and your StackPanel with the label to the right side.
<DockPanel>
<DockPanel
DockPanel.Dock="Top"
LastChildFill="False" >
<RadioButton
DockPanel.Dock="Left"
Content="_Programs"
IsChecked="{Binding Path=ProgramBanksSelected}"
IsEnabled="{Binding Path=ProgramsEnabled}"
Margin="8" />
<StackPanel
DockPanel.Dock="Right">
<Label
Content="Master"
Height="28"
Name="MasterFileStatus"
VerticalContentAlignment="Center"/>
</StackPanel>
</DockPanel>
...
Solution 5
Use the Stackpanel orientation type in a nested fashion as shown in the sample. The Grid Width is set to a parent width in order to achieve full width.
<StackPanel x:Name="stackBlah" Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Grid Width="{Binding ActualWidth, ElementName=stackBlah}" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Grid.Column="0" HorizontalAlignment="Left" >
<Button Content="Some button" />
</StackPanel>
<StackPanel Grid.Column="1" HorizontalAlignment="Right">
<ToggleSwitch Header="Some toggle" AutomationProperties.Name="ToggleNotifications"/>
</StackPanel>
</Grid>
</StackPanel>
</StackPanel>
Michel Keijzers
I'm a professional software engineer, working at Altran. I have interest in OO languages and have C++/C# knowledge (MCTS, WinForm, WPF applications). Until recently, I wrote an app for Korg music synthesizers (PCG Tools) and try to learn myself WPF at the same time. Lately, I'm into Arduino/STM32, learning the basics (and more) of electronics, and trying to build a MIDI/DMX device for MIDI keyboards and DMX512 lighting devices.
Updated on July 05, 2022Comments
-
Michel Keijzers almost 2 years
I have the following code:
<DockPanel> <StackPanel DockPanel.Dock="Top" Orientation="Horizontal"> <RadioButton Content="_Programs" IsChecked="{Binding Path=ProgramBanksSelected}" IsEnabled="{Binding Path=ProgramsEnabled}" Margin="8" /> <StackPanel> <Label Content="Master" Height="28" Name="MasterFileStatus" VerticalContentAlignment="Center"/> </StackPanel> </StackPanel> ...
The radio button should be placed on the left side in the stack panel (I removed some buttons for not cluttering the example) and the label (which I put temporarily in a nested StackPanel) should be on the right side.
I tried already lots of combinations of alignments but I cannot get the label on the right side. What should I add to accomplish this?
-
Kevin DiTraglia over 11 yearsYou really can't ask too much of stack panels, as soon as you want any kind of semi-advanced structure just go for a grid
-
pasx about 11 yearsThe right answer is to use a DockPanel as in this post: stackoverflow.com/questions/2023201/…
-
jwize almost 3 yearsAnd to add horizontal alignment right to the last element.
-
-
Kevin DiTraglia over 11 yearsYour first example will not work, they will still stack horizontally as space allows and the alignment won't do anything.
-
newfurniturey over 11 years@KDiTraglia Yeah, just tested - you're right; When
Orientation="Horizontal"
, it ignores theHorizontalAlignment
; removing now, thanks =] -
Michel Keijzers over 11 yearsI guess that would work, however I will wait for more answers, because with StackPanels I have the benefit that when the screen is made less wide, the items will wrap up, which I loose when I use a grid.
-
H.B. over 11 years@MichelKeijzers: If you want something fancy like that you may need to implement your own panel.
-
Michel Keijzers over 11 yearsThanks for the answer ... I don't know if I prefer your solution about not right aligning in that case, but that is outside of the question I asked.
-
Knasterbax over 10 yearsWorks fine. Thank you!
-
Mrinmoy about 5 yearsThanks for tip. I took all ColumnDefinition Width="*" to equally distribute
-
Jonathan Tuzman almost 4 yearsThis is a super great solution. You don't actually need the
StackPanels
though, if each panel only has one child. -
Rajshekar Reddy over 2 yearsElegant... Does the job without much of grid definitions.
-
Neha about 2 yearsAdditionally A little binding trick worked when grid is inside stackpanel . this makes grid width expand so that button appears on left and right corners of the screen. <StackPanel x:Name="sp1" Margin="10" Orientation="Horizontal"> <Grid Width="{Binding ElementName=sp1, Path=ActualWidth}" >