Yesterday we dove into the grid, in all likelihood it will be the container you’ll use the most. There’s another container control however that’s very popular, the StackPanel. You will often see the StackPanel used in demos because of it’s simplicity. It’s also used frequently for nesting controls inside another control.
Many controls have a contents property. The contents properties typically can hold only one thing, however that one thing can be a StackPanel, which in turn can house multiple items.
In Visual Studio, either start a new Windows WPF Project, or simply add a new Window (make sure to pick “Add New Item”, then “Window (WPF)”, if you had picked “Add New Windows Form” you’d have gotten and old fashioned WinForm) to the current sample we were using yesterday. Also, to make this the startup form, open the App.xaml file and change the startupuri to the new form:
<Application x:Class=“WPFSample001.App“
xmlns=“http://schemas.microsoft.com/winfx/2006/xaml/presentation“
xmlns:x=“http://schemas.microsoft.com/winfx/2006/xaml“
StartupUri=“Window2.xaml“
>
<Application.Resources>
</Application.Resources>
</Application>
You can see I changed mine to Window2.xaml. OK, back to the Window2.xaml file.
In the XAML area remove the <Grid> tags and add the following code:
<StackPanel>
<Button>Here’s a Button</Button>
<TextBlock HorizontalAlignment=“Center“ Background=“Red“>Hello There</TextBlock>
<TextBox>A Text Box</TextBox>
<CheckBox>Check Me!</CheckBox>
<Button>One More Button</Button>
</StackPanel>
What you will see is the controls stacked in a vertical fashion:
The StackPanel only has one real property with fiddling with, that’s the Orientation. By default Orientation is Vertical, however you can set it to Horizontal thusly:
<StackPanel Orientation=“Horizontal“>
When you do, you’ll see this (well, once you resize the window a tad to be able to see everything):
This would be useful if you wanted to create a status bar, or row of action buttons in your app.
I said the Orientation property was the main one you’ll be adjusting, however there is one more you may need, although probably not often. That’s the margin property. In the example below I set the margin to 20 so you can easily see the effect.
<StackPanel Margin=“20“ Orientation=“Horizontal“>
You may, however want things oriented a bit differently. The StackPanel lacks an easy way to do this, however we can achieve a rotated text effect using the RenderTransform method of the various controls. Take a look:
Here’s the source (with the Window tags omitted):
<Window x:Class=“WPFSample001.Window2“
xmlns=“http://schemas.microsoft.com/winfx/2006/xaml/presentation“
xmlns:x=“http://schemas.microsoft.com/winfx/2006/xaml“
Title=“WPFSample001“ Height=“152“ Width=“400“
>
<StackPanel Orientation=“Horizontal“>
<Button RenderTransformOrigin=“0.5,0.5“>
<Button.RenderTransform>
<RotateTransform Angle=“270“ />
</Button.RenderTransform>
Here’s a Button
</Button>
<TextBlock RenderTransformOrigin=“0.5,0.5“ VerticalAlignment=“Center“ Background=“Red“>
<TextBlock.RenderTransform>
<RotateTransform Angle=“90“ />
</TextBlock.RenderTransform>
Hello There
</TextBlock>
<TextBox>A Text Box</TextBox>
<CheckBox>Check Me!</CheckBox>
<Button>
<TextBlock RenderTransformOrigin=“0.5,0.5“ VerticalAlignment=“Center“ HorizontalAlignment=“Center“>
<TextBlock.RenderTransform>
<RotateTransform Angle=“270“ />
</TextBlock.RenderTransform>
One More Button
</TextBlock>
</Button>
</StackPanel>
</Window>
What I especially want to point out are the two buttons. In the first button, “Here’s a Button”, I applied the RenderTransform to the entire button. When I did this, WPF flipped the button on it’s side, but did not resize it. Instead, it left it at the default size the StackPanel had come up with. Not pretty, certainly not desireable for your app.
The solution then, is to do what I did for button two, the “One More Button” button. I replaced the contents with a TextBlock. I then used the same RenderTransform technique I had done with the “Hello There” TextBlock to flip the text on it’s side. Now it looks like the buttons text is flipped sideways, but the button retains the correct sizing.
The StackPanel will be an often used tool in your arsenal. Indeed, from what I have seen it may be THE most used WPF control in your kit.
hi,
how can i add controls into stackpanel programmatically?
Good question, most of my research so far has been from the XAML end. Let me look into it and I’ll have something in a day or two.
Arcane
OK xpendo, I found a solution for you. I’ll have a new posting with the solution in the blog this Friday.
Arcane
thanks for it 🙂
This helped in my search to have a vertical stack panel of 90 degree rotated buttons – now I know why the buttons are outside the stack panel. However – I am trying to do below programatically. I have crated the TextBlock but still having trouble linking to TextBlock to buttto. Tried putting TextBlock as content of button but that did not work.
-Eric
One More Button
I meant to say – horizontal stack panel of 90 degree buttons.
Thanks, Eric
I was forgetting to programatically set the RenderTransformOrigin so the TextBock would rotate around the proper origin.
button = new Button();
TextBlock tb = new TextBlock();
tb.Text = name;
tb.RenderTransformOrigin = new Point(.5,.5);
RotateTransform rt = new RotateTransform();
rt.Angle = 90;
tb.RenderTransform = rt;
button .Content = tb;
stackPanel.Children.Add(button);
is it possible to add and remove controls programmitically?
i want to add combo box based on user input and remove it based on user input.
thank u,
sandy
Very informative text. I’ve found your blog via Yahoo and I’m really glad about the information you provide in your articles. Btw your blogs layout is really broken on the Chrome browser. Would be cool if you could fix that. Anyhow keep up the great work!