Adding more than one child to a WPF StatusBar
results in poor layout with little option to customize. For example, this code:
<Window x:Class="StatusBar.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">
<DockPanel>
<StatusBar DockPanel.Dock="Bottom">
<StatusBarItem>
<TextBlock>Ready</TextBlock>
</StatusBarItem>
<StatusBarItem>
<TextBlock>Set</TextBlock>
</StatusBarItem>
</StatusBar>
<Label>Main Content</Label>
</DockPanel>
</Window>
Results in:
This is not the ideal layout, since the "Set" is squeezed right up against the "Ready".
How do I gain full control over the layout of the WPF StatusBar
control?
A StatusBar is a horizontal area at the bottom of a window where an application can display status information.
There are six defined panel classes (Canvas, DockPanel, Grid, StackPanel, VirtualizingStackPanel, and WrapPanel) that are designed specifically for creating application UI.
The ProgressBar tag in XAML represents a WPF ProgressBar control. The Width and Height properties represent the width and the height of a ProgressBar. The Name property represents the name of the control, which is a unique identifier of a control.
By default, the StatusBar
uses a DockPanel
to position its children. This works fine for one item, but tends to make things messy and inconvenient when working with more than one child.
To gain a high level of control over the positioning of status bar children, you can swap out the DockPanel
for a Grid
:
<Window x:Class="StatusBar.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"> <DockPanel> <StatusBar DockPanel.Dock="Bottom"> <StatusBar.ItemsPanel> <ItemsPanelTemplate> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="4*"/> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> </Grid> </ItemsPanelTemplate> </StatusBar.ItemsPanel> <StatusBarItem> <TextBlock>Ready</TextBlock> </StatusBarItem> <StatusBarItem Grid.Column="1"> <ProgressBar Value="30" Width="80" Height="18"/> </StatusBarItem> <StatusBarItem Grid.Column="2"> <TextBlock>Set</TextBlock> </StatusBarItem> <StatusBarItem Grid.Column="3"> <TextBlock>Go!</TextBlock> </StatusBarItem> </StatusBar> <Label>Main Content</Label> </DockPanel> </Window>
This results in:
For a more in-depth discussion, please visit my blog post here.
Actually, following Kent's reply I tried this and it works fine:
<StatusBar>
<StatusBarItem DockPanel.Dock="Right">
<TextBlock>Go!</TextBlock>
</StatusBarItem>
<StatusBarItem DockPanel.Dock="Right">
<TextBlock>Set</TextBlock>
</StatusBarItem>
<StatusBarItem DockPanel.Dock="Right">
<ProgressBar Value="30" Width="80" Height="18"/>
</StatusBarItem>
<!-- Fill last child is true by default -->
<StatusBarItem>
<TextBlock>Ready</TextBlock>
</StatusBarItem>
</StatusBar>
Just for the sake of reference for those reading the excellent answers above I'd like to suggest something even more simpler that achieves the same results. (Using neither DockPanel
nor StatusBar
).
<Window>
.
.
<Grid Margin="2">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="15"/>
</Grid.RowDefinitions>
<SomeContainer Grid.Row="0" /> <!-- Main Content.. -->
<Grid Grid.Row="1">
<!-- Status bar laid out here (using similar approach)-->
</Grid>
</Window>
Disclaimer : This was long ago at a time when I was starting out with WPF.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With