I have Stackpanel which is the base of my window, instead of grid.... in this Stackpanel which is vertical, I have tons of items, including labels and textboxes... I have like 20+ of these... the problem is, I need to Stackpanel's horizontal alignment to be set to stretch because I need some of the items to have the width of the whole window... but I also want all the items to be aligned to left side of the window... currently in order to achieve what I wanted I have to specify for each control inside of the Stackpanel to have horizontal alignment = Left... this is very annoying because I have tons of controls that have that horizontal alignment specified again and again, and it makes the xaml ugly... is there a prettier way of solving this problem? (also I should note that I tried setting the Stackpanel's flow direction to left but I did not work)
-
Maybe you should wrap each control or control group in another container Grid, StackPanel, etc. So you set the container to be strech but the control to be aligned left – Carlos487 Aug 24 '15 at 15:15
-
Some things that immediately come to mind is an `ItemsControl` with the `ItemsPanelTemplate` setting the alignment (will wrap each item in a `ContentPresenter`), or trying to use `
` to set a generic style for `FrameworkElement` or `Control` with the alignment properties. – Rachel Aug 24 '15 at 15:16 -
I think I'd be looking to get away from StackPanels: http://stackoverflow.com/questions/12150914/aligning-controls-on-both-left-and-right-side-in-a-stack-panel-in-wpf . StackPanels have a tendency to get in the way when you start using them for anything beyond *really simple* layout tasks. @Rachel's suggestion to use an ItemsControl is probably a good one, or just use a Grid. – goobering Aug 24 '15 at 15:22
-
@Rachel could you please post your suggestion with example? I don't understand how to use it... – David Shnayder Aug 24 '15 at 17:56
-
If you need some of the controls to be stretched and some to be left-aligned, I don't see any other way than to specify this for each control individually. – vesan Aug 24 '15 at 23:44
3 Answers
maybe a iteration over children of stackpanel and set the Horizontal alignment would be suitable?
Panel.Children.OfType<Control>().ToList().ForEach(child=>child.HorizontalAlignment =HorizontalAlignment.Left);

- 460
- 3
- 10
-
even if I won't use it, this is a great idea and you thought me something I did not think about so thank you! – David Shnayder Aug 24 '15 at 17:35
-
Actually, I just tried that and there is no .OfType function inside panel.children, and there is no .ToList inside as well... – David Shnayder Aug 24 '15 at 17:57
-
[You should really use a different approach here, an ItemsControl
comes to mind, or a different panel/panels. But if you want to continue with this so...]
In your StackPanel
set a style for FrameworkElement
that will set the alignment to all children (recursively).
<StackPanel.Resources>
<Style TargetType="{x:Type FrameworkElement}">
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
</StackPanel.Resources>
NOTE: it might cause more headache than it solves.

- 6,189
- 2
- 22
- 29
-
this appears to not work (not sure why). i've tested with Buttons and for some reason their justification does not change. it also does not work with Control as the type – d.moncada Aug 24 '15 at 16:21
-
-
This will not work. See this question: http://stackoverflow.com/questions/4131034/how-to-target-all-controls-wpf-styles – vesan Aug 24 '15 at 23:42
I'd recommend switching to an ItemsControl, and setting your ItemContainerStyle
with your alignment properties.
An ItemsControl
wraps each item in a ContentPresenter
, and the ItemContainerStyle
would apply to the ContentPresenter
that wraps each item.
XAML code would look something like this :
<ItemsControl>
<!-- ItemContainerStyle -->
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
</ItemsControl.ItemContainerStyle>
<!-- controls here -->
</ItemsControl>
Alternatively, you could use code-behind to just set this property of all items in the Loaded method. This might actually perform a bit better because you won't have the extra ContentPresenter
layer in the UI.
private void MyStackPanel_Loaded()
{
foreach(FrameworkElement ctl in MyStackPanel.Children)
{
ctl.HorizontalAlignment = HorizontalAlignment.Left;
}
}

- 130,264
- 66
- 304
- 490