WPF Sample Series – Stretch ToolBar Width Of Window

imageone

This is the next sample in the WPF Sample Applications Series. The purpose of the Sample Series is to provide concise code solutions for specific programming tasks. This sample provides a brief description of the problem, the solution and full source code.

I’m working on a WPF application that calls for the ToolBar to stretch across the top of the Window, with the Help button right aligned.  If the form width is less than the width of the ToolBars, the the ToolBars must display the ToolBar buttons using the ToolBar overflow feature.

My co-worker surfed around the web to see how another developer may have done this, but could not find any examples of how to do this.  So we sat down and spent the 10 minutes to lay up the above form and post this sample.

Window XAML Code

Things To Learn From This Code

  • How to use a Grid control to layout a WPF business form.
  • How to have a ToolBar consume the width of the form.
  • How to right align the Help button on the ToolBar.
  • How to capture ToolBar button click events in a single RoutedEventHandler.
<Window 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
  x:Class="Window1" 
  Title="ToolBar Full Width Sample" Height="300" Width="300" 
  Background="#FFFFFFFF"> 

  <Grid> 
    <Grid.RowDefinitions> 
        <RowDefinition Height="Auto"/> 
        <RowDefinition Height="*"/> 
        <RowDefinition Height="Auto"/> 
    </Grid.RowDefinitions> 

    <DockPanel Grid.Row="0" LastChildFill="False" 
               HorizontalAlignment="Stretch" Width="Auto" 
               Background="#FFF2F2F2"> 
      <ToolBar x:Name="tbToolBar" DockPanel.Dock="Left" 
               Background="{x:Null}"> 

        <Button ToolTip="New"> 
            <Image Source="New.png"/> 
        </Button> 
        <Button ToolTip="Save"> 
            <Image Source="Save.png"/> 
        </Button> 
        <Button ToolTip="Delete"> 
            <Image Source="Delete.png"/> 
        </Button>                 

      </ToolBar> 
      <ToolBar x:Name="tbToolBarHelp" DockPanel.Dock="Right" 
               Background="{x:Null}"> 

        <Button ToolTip="Help"> 
            <Image Source="Help.png"/> 
        </Button> 

      </ToolBar> 
    </DockPanel> 
    <Border Grid.Row="1" Background="#FFE8F9FF" 
            Padding="20,0,0,0" BorderBrush="#FF0032AA" 
            BorderThickness="0,1,0,0"> 

      <Grid> 
        <Grid.RowDefinitions> 
          <RowDefinition Height="Auto"/> 
          <RowDefinition Height="Auto"/> 
          <RowDefinition Height="Auto"/> 
          <RowDefinition Height="Auto"/> 
        </Grid.RowDefinitions> 

        <Grid.ColumnDefinitions> 
          <ColumnDefinition Width="75"/> 
          <ColumnDefinition Width="*"/> 
        </Grid.ColumnDefinitions> 
        <TextBlock Grid.Column="0" Grid.ColumnSpan="2" 
                   Text="New User Form" Margin="0,10,0,10" 
                   FontSize="18" FontWeight="Bold" 
                   Foreground="#FF0024A6"/> 

        <TextBlock Grid.Column="0" Grid.Row="1" 
                   Text="Name"/> 
        <TextBlock Grid.Column="0" Grid.Row="2" 
                   Text="Email"/> 
        <TextBlock Grid.Column="0" Grid.Row="3" 
                   Text="Password"/> 
        <TextBox Grid.Column="1" Grid.Row="1" Width="150" 
                 HorizontalAlignment="Left"/> 
        <TextBox Grid.Column="1" Grid.Row="2" Width="150" 
                 HorizontalAlignment="Left" 
                 Margin="0,5,0,0"/> 
        <PasswordBox Grid.Column="1" Grid.Row="3" Width="150" 
                     HorizontalAlignment="Left" 
                     Margin="0,5,0,0"/> 
      </Grid> 
    </Border> 
    <StatusBar Grid.Row="2"> 
        <StatusBarItem Content="This is the StatusBar"/> 
    </StatusBar> 
  </Grid> 
</Window> 

Use Grid Control To Layout Form

I’ve seen many different layout techniques for docking a ToolBar at the top, form controls in the middle and StatusBar docked at the bottom.  A DockPanel control works great for doing this.  However, if you use a Grid control, you can accomplish the same thing and have a little bit more flexibility.  So for this example, I’ve chosen the Grid control as the Layout root control for the Window.  Three rows, the top and bottom rows have their height set to Auto and the middle row is set to consume the remaining space.

When I comes to the ToolBar layout, I tried 3 or 4 different layouts and like the above one the best.

Using the DockPanel control as the container for the two ToolBar controls makes the most sense here because if I need to add a third ToolBar later, I can just position it and dock it according to my layout requirements.

Take notice of the LastChildFill property on the DockPanel.  You must set it to False, otherwise the last ToolBar added to the DockPanel would consume the available space and the ToolBar would not look correct.

By placing the DockPanel.Dock attached property on the two child ToolBars, we can control which side of the DockPanel each of the ToolBars will be docked to.

Another nice feature of laying the ToolBars out like this is, if the container Window width is smaller than the ToolBar width, the ToolBar will automatically go into its overflow button display mode and the user can click on the black down arrow graphic at on the right side of the ToolBar to display the hidden ToolBar buttons.

Narrow Window – Right Toolbar Collapsed

imagetwo

Notice how the form has been reduced to a very small width.  The right ToolBar has been collapsed and the black down arrow graphic is visible.  I have click the graphic and the Help button is now visible.

Capturing ToolBar Click Events

Partial Public Class Window1 
  Inherits System.Windows.Window 

  Public Sub New() 
    InitializeComponent() 
  End Sub 

  Private Sub Window1_Loaded(ByVal sender As Object, _ 
    ByVal e As System.Windows.RoutedEventArgs) Handles _ 
    Me.Loaded 

    'set up a RoutedEventHandler for all ToolBar buttons. 
    ' 
    Me.dpToolBarContainer.AddHandler( _ 
      Button.ClickEvent, New RoutedEventHandler( _ 
      AddressOf ToolBarButton_Click)) 

  End Sub 

  Private Sub ToolBarButton_Click(ByVal sender As _ 
    Object, ByVal e As System.Windows.RoutedEventArgs) 

    'TODO developers handle your button click events here 
    ' 
    'cast the e.OriginalSource as a button, then get your 
    '  command from the button and act upon it 
    ' 
    'Dim btn As Button = CType(e.OriginalSource, Button) 

  End Sub 

  Private Sub Window1_Unloaded(ByVal sender As Object, _ 
    ByVal e As System.Windows.RoutedEventArgs) Handles _ 
    Me.Unloaded 

    'clean up by removing the handler we added in the loaded event 
    ' 
    Me.dpToolBarContainer.RemoveHandler( _ 
      Button.ClickEvent, New RoutedEventHandler( _ 
      AddressOf ToolBarButton_Click)) 

  End Sub 

End Class 

The above code takes advantage of the WPF RoutedEvent architecture by listening for all ToolBar button Click events in their parent container (grandparent actually).  Since all the ToolBar buttons are contained within the DockPanel or child controls of the DockPanel, we can place a single routed event handler on the DockPanel and listen for the Click event. 

Notice how I call RemoveHandler on the Unload event.  I’m a firm believer in explicit clean up, disposing and de-referencing.

If you are not familar with WPF RoutedEvents, RoutedEventHanders or RoutingStrategys please see the following two articles I have written.  They both has examples of each.

When you write your own code, you’ll need to come up with a strategy for handling the ToolBar button Click events.  When you add your buttons to the ToolBar, you’ll need to mark the button with the command that button represents.  There are several ways to do this.  You can use the CommandParameter and place your command there, you can use the built it WPF Command system and assign a Command to the Command property, you can place a value in the button Tag property, etc.  Many ways to mark a button with its command.  Then just test the button for its command that you have assigned and take appropriate action.

Please keep in mind, for “real world” applications, the ToolBar should be in a UserControl or CustomControl.  The above code is simple layout instruction and all the code is in one form to make it easier to understand.

Source Code: After downloading the source code you MUST change the file extension from .zip.DOC to .zip. This is a requirement of WordPress.com.

DownLoad Source Code 18KB

Hope you can learn just a little bit more about WPF from this article and the Sample Series.

Just a grain of sand on the worlds beaches.

Comments are closed.

Follow

Get every new post delivered to your Inbox.

Join 248 other followers