Kent Boogaart
Kent Boogaart

Reputation: 178700

How do I customize the WPF StatusBar layout?

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:

enter image description here

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?

Upvotes: 33

Views: 46374

Answers (4)

Pavel Popov
Pavel Popov

Reputation: 121

You can use a container like StackPanel to move a group of status bar items to the right

<StatusBarItem>
    <Button Content="Left Aligned Button"/>
</StatusBarItem>
<StatusBarItem HorizontalAlignment="Right">
    <StackPanel Orientation="Horizontal">
        <StatusBarItem>
            <Button Content="Right Aligned Button 1"/>
        </StatusBarItem>
        <StatusBarItem >
            <Button Content="Right Aligned Button 2"/>
        </StatusBarItem>
    </StackPanel>
</StatusBarItem>

Upvotes: 0

Kent Boogaart
Kent Boogaart

Reputation: 178700

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:

enter image description here

For a more in-depth discussion, please visit my blog post here.

Upvotes: 89

Robin Maben
Robin Maben

Reputation: 23064

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.

Upvotes: 2

Afshin
Afshin

Reputation: 540

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>

Upvotes: 13

Related Questions