Whenever I started an application in Windows Forms (WF), the first thing I did was add controls in the following order:
ToolBar– a drop-down, nestable menu that usually contains most of the program’s featuresToolStrip– a row of buttons for the most frequently used actionsStatusStrip– information about the state of the application
In WF this was trivial. You simply added them with a click in the ToolBox, then clicked on them and added as many items as you needed, and finally wrote the corresponding handlers. In WPF all of this is more complicated.
The control with the closest resemblance to ToolBar is called Menu. It is declared roughly like this:
<!--The documentation says IsMainMenu determines whether the Menu receives activation notifications. I have no idea what that is supposed to mean-->
<!--You do not even need to set Grid.Row and Grid.Column on a Menu inside a Grid - they default to 0,0-->
<Menu IsMainMenu="False" Name="mainMenu">
<!--Arbitrarily nested MenuItem elements - those directly in the Menu are laid out horizontally, the rest below them vertically-->
</Menu>The second of the controls mentioned above that has its counterpart in WPF is ToolStrip, whose WPF equivalent is ToolBarTray. It is a little bit harder than Menu, but it is still nothing scary, and maybe it just seems that way to me:
<ToolBarTray>
<!--Band is the vertical order, BandIndex the horizontal one-->
<ToolBar Band="0" BandIndex="0">
<!--Individual components can be placed here-->
</ToolBar>
</ToolBarTray>And the third one is StatusBar. This one is again dead simple:
<StatusBar>
<!--Using a Grid inside the StatusBar is recommended, because you can set its columns to * or Auto-->
<Grid></Grid>
<!--The individual StatusBar items go here-->
</StatusBar>You can find the complete source code here:
<Window x:Class="BasicAppLayout.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style TargetType="TextBlock" x:Key="StatusBarTextBlock">
<Setter Property="TextWrapping" Value="NoWrap" />
<Setter Property="TextTrimming" Value="CharacterEllipsis" />
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<!--The optimal height for the Menu is 20-->
<RowDefinition Height="20"></RowDefinition>
<!--The optimal height for the ToolBarTray is 27-->
<RowDefinition Height="27"></RowDefinition>
<RowDefinition Height="25"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="25"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Menu IsMainMenu="True" Name="mainMenu">
<MenuItem Header="1">
<MenuItem Header="1-1" Name="miOneOne" Click="miOneOne_Click"></MenuItem>
<MenuItem Name="outerMenu2" Header="1-2">
<!--A MenuItem can be nested inside another MenuItem as deeply as you like-->
<MenuItem Header="1-2-1" Name="miOneTwoOne" Click="miOneTwoOne_Click"></MenuItem>
</MenuItem>
<MenuItem Header="1-3" Name="miOneThree" Click="miOneThree_Click"></MenuItem>
</MenuItem>
<MenuItem Header="2">
<MenuItem Header="2-1" Name="miTwoOne" Click="miTwoOne_Click"></MenuItem>
</MenuItem>
</Menu>
<ToolBarTray Background="AntiqueWhite" Grid.Column="0" Grid.Row="1">
<!--This ToolBar will be second, because it has BandIndex="1"-->
<!--Band is the vertical order, BandIndex the horizontal one-->
<ToolBar Band="0" BandIndex="1">
<Button>New</Button>
<Button>Open</Button>
<Button>Exit</Button>
</ToolBar>
<!--This ToolBar will come before the first one, because it has BandIndex="0"-->
<ToolBar BandIndex="0" Band="0">
<Image Width="25" Height="25">
<Image.Source>
<!--I have the Undo.png image in the project root without any additional settings-->
<BitmapImage UriSource="Undo.png"></BitmapImage>
</Image.Source>
</Image>
<!--Alternatively, if you also want text there, you can do it like this, but be warned - by default it does not look very nice. In addition, you have to put all of this (Image+TextBlock) into a StackPanel and then into a Button-->
<!-- <TextBlock Text="Undo">
</TextBlock>
-->
<Button>Redo</Button>
</ToolBar>
<!--The following ToolBar will not be visible, because the row is only 27 high-->
<ToolBar Band="1" BandIndex="0">
<Button>Paint</Button>
<Button>Editor</Button>
<Separator></Separator>
<Button>Cut</Button>
<Button>Copy</Button>
<Button>Paste</Button>
<Separator></Separator>
<Button>Find</Button>
<Button>Replace</Button>
</ToolBar>
</ToolBarTray>
<Grid Grid.Row="2" Grid.Column="0" Background="Red"></Grid>
<WebBrowser Name="webBrowser" Grid.Row="3" Grid.Column="0"></WebBrowser>
<StatusBar Gri="" d.Row="4" Grid.Column="0" Name="statusBar">
<Grid>
<Grid.ColumnDefinitions>
<!--For item 1; thanks to Auto it always takes only as much space as it needs-->
<ColumnDefinition Width="Auto"></ColumnDefinition>
<!--For the progress bar-->
<ColumnDefinition Width="Auto"></ColumnDefinition>
<!--For the status-->
<ColumnDefinition Width="*"></ColumnDefinition>
<!--For the error-->
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<!-- Item 1 -->
<StackPanel Orientation="Horizontal" Grid.Column="0">
<TextBlock Style="{StaticResource StatusBarTextBlock}">Item 1</TextBlock>
</StackPanel>
<!-- Progress bar -->
<StackPanel Orientation="Horizontal" Grid.Column="1">
<Separator></Separator>
<ProgressBar IsIndeterminate="False" Padding="5, 0, 0, 0" Width="200" Value="50"></ProgressBar>
</StackPanel>
<!-- Status item -->
<!--The text in this item (and in the item below) can be long and needs to be trimmed if it is too long - an ellipsis is shown
at the visible end. The ellipsis is set by the TextTrimming property set to CharacterEllipsis in the StatusBarTextBlock style
If you set the column width to Auto instead of *, the column would be allowed to grow indefinitely and would not be shortened at the expense of the 4th TextBlock
-->
<DockPanel LastChildFill="True" Grid.Column="2">
<Separator DockPanel.Dock="Left"></Separator>
<TextBlock Style="{StaticResource StatusBarTextBlock}" ToolTip="This is a very long text and it will definitely be trimmed" Text="This is a very long text and it will definitely be trimmed"></TextBlock>
</DockPanel>
<!-- Error item -->
<DockPanel LastChildFill="True" Grid.Column="3">
<Separator DockPanel.Dock="Left"></Separator>
<Image DockPanel.Dock="Left" Margin="2,0" Source="error.gif" Width="16"></Image>
<TextBlock Style="{StaticResource StatusBarTextBlock}" ToolTip="Any error that occurs will be shown here in this TextBlock" Text="Any error that occurs will be shown here in this TextBlock"></TextBlock>
</DockPanel>
</Grid>
</StatusBar>
</Grid>
</Window>And the result will then look something like this:

