Category Archives: Visual Studio 2008

Wrapping up containers with the WPF WrapPanel

Originally I hadn’t planned to mention the WrapPanel, because in my view it’s not an overly useful control. I have a hard time imagining when you might want to use it, but in playing with it I actually came up with one scenario, perhaps someone will be able to offer some more.

Using the control is easy, simply put <WrapPanel> and it’s ending tag in a Window or Page, then put the controls inside you want. Then as you resize the window, the controls inside will automatically shift around to make use of the available space.

For today’s example, create the WrapPanel tags, and inside put 8 buttons.

  <WrapPanel>

    <Button Width=50>1</Button>

    <Button Width=50>2</Button>

    <Button Width=50>3</Button>

    <Button Width=50>4</Button>

    <Button Width=50>5</Button>

    <Button Width=50>6</Button>

    <Button Width=50>7</Button>

    <Button Width=50>8</Button>

  </WrapPanel>

I then stretched out the window so you can see all 8 horizontally:

wpf019 

Now if I simply resize the window a bit, you’ll see the controls rearrange themselves automatically:

wpf020

And of course I can make them all go vertical if I want:

wpf021 

The one way I can think this might be useful is if you were to create a floating toolbar. In that form it might be handy to have the toolbar buttons moving around. Odds are there are better ways to create a floating toolbar, but if you needed something simple this might be an answer for you.

Other than that one example I can’t think of a lot of uses for it, but if you know some by all means post a comment. Meanwhile at least you’ll be familiar with the WrapPanel container.

Advertisements

The WPF DockPanel

The next container control we need to look at is the DockPanel. It’s a special use control, the individual controls placed inside the DockPanel control can be docked to one of the four sides. Let’s look at an example.

  <DockPanel>

    <Button DockPanel.Dock=Left>Left</Button>

    <TextBlock>Rest of it</TextBlock>

  </DockPanel>

(Note in the code examples I’ve omitted the WINDOW tag, that way you can use this in either Visual Studio or XamlPad) This code produces

wpf016

As you can see, the docked button takes up the entire left side. We could have also set the Dock property to Top, Right, or Bottom. We can have multiple controls with dock property. The order in which they are added is important.

The first control will take up all the space on the docked side first. Then each control will take up the remaining space on the side they are docked on. If multiple controls are docked to the same side, they will be stacked up in the order they were added, the first control being the outermost.

The remaining control added without a dock property will be placed in the middle, and take up all the remaining space. Let’s look at a quick sample that is somewhat realistic.

  <DockPanel>

    <StackPanel DockPanel.Dock=Left>

      <Label>MAIN MENU</Label>

      <Button>Top Left</Button>

      <Button>Left 2</Button>

      <Button>Left 3</Button>

      <Button>Bottom Left</Button>

    </StackPanel>

    <StackPanel DockPanel.Dock=Top Orientation=Horizontal>

      <Label>Secondary Menu</Label>

      <Button>Top Btn 1</Button>

      <Button>Top Btn 2</Button>

    </StackPanel>

    <Grid>

      <Grid.RowDefinitions>

        <RowDefinition></RowDefinition>

        <RowDefinition></RowDefinition>

        <RowDefinition></RowDefinition>

      </Grid.RowDefinitions>

      <Grid.ColumnDefinitions>

        <ColumnDefinition></ColumnDefinition>

        <ColumnDefinition Width=2*></ColumnDefinition>

      </Grid.ColumnDefinitions>

      <Label Grid.Row=0 Grid.Column=0 HorizontalAlignment=Right>First Name:</Label>

      <TextBox Grid.Row=0 Grid.Column=1></TextBox>

      <Label Grid.Row=1 Grid.Column=0 HorizontalAlignment=Right>Last Name:</Label>

      <TextBox Grid.Row=1 Grid.Column=1></TextBox>

    </Grid>

  </DockPanel>

Will produce this lovely window:

wpf017

Now you can begin to glean the usefulness of the DockPanel. You should note because the StackPanel with “Secondary Menu” in it is listed in the XAML after the MAIN MENU StackPanel, it is to the right.

If you simply move the secondary StackPanel above the MAIN MENU one in the XAML, you’ll see the Secondary Menu now goes all the way across, and the Main Menu is now playing second fiddle, thusly:

wpf018

You can add more items to the other sides as well, for example you could put some sort of status bar across the bottom, or another panel over on the right.

As you can see, while it’s not a container control you’ll use every day, the DockPanel can be exteremely useful and flexible in Window design.

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.

New version of CodeRush/RefactorPro

Just thought I’d take a short break from WPF to make you aware there has been a new release to that wonderful Visual Studio add-in CodeRush. The product has now broken the 100 refactorings mark!

You can read the announcement from DevExpress at http://www.devexpress.com/Home/Announces/CodeRush25.xml

If you are not familiar with DevExpress’ CodeRush/RefactorPro tools, you can read my original post at https://arcanecode.wordpress.com/2007/01/09/visual-studio-add-ins-coderush/

The new version already works with Visual Studio 2008. Talk about being on the ball, VS2008 is still in Beta and they’ve already got refactorings out there just for it!