Stacking the deck with the WPF StackPanel

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:

 [Picture of StackPanel in Action]

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):

[Picture of StackPanel with Horizontal layout] 

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>

[Picture of StackPanel with Margin of 20] 

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:

[Picture of StackPanel with Rotated Text] 

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.

About these ads

10 Responses to “Stacking the deck with the WPF StackPanel”

  1. xpendo Says:

    hi,

    how can i add controls into stackpanel programmatically?

  2. arcanecode Says:

    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

  3. arcanecode Says:

    OK xpendo, I found a solution for you. I’ll have a new posting with the solution in the blog this Friday.

    Arcane

  4. Adding WPF Controls Progrrammatically « Arcane Code Says:

    [...] September 7th, 2007 — arcanecode On August 29th I wrote a posting about the StackPanel (http://arcanecode.wordpress.com/2007/08/29/stacking-the-deck-with-the-wpf-stackpanel/). A commentor asked “how do you add controls programmatically?” Good question, and it turns out [...]

  5. yvisek Says:

    thanks for it :)

  6. Eric Coulson Says:

    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

  7. Eric Coulson Says:

    I meant to say – horizontal stack panel of 90 degree buttons.

    Thanks, Eric

  8. Eric Coulson Says:

    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);

  9. sandy Says:

    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

  10. Laveta Klitz Says:

    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!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 106 other followers

%d bloggers like this: