如何自定义 WPF 状态栏布局?

Posted

技术标签:

【中文标题】如何自定义 WPF 状态栏布局?【英文标题】:How do I customize the WPF StatusBar layout? 【发布时间】:2010-11-25 07:16:46 【问题描述】:

将多个子级添加到 WPF StatusBar 会导致布局不佳,几乎没有自定义选项。例如这段代码:

<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>

结果:

这不是理想的布局,因为“Set”被挤压在“Ready”上。

如何完全控制 WPF StatusBar 控件的布局?

【问题讨论】:

【参考方案1】:

默认情况下,StatusBar 使用 DockPanel 来定位其子级。这适用于一件物品,但在与多个孩子一起工作时往往会使事情变得混乱和不便。

要对状态栏子项的位置进行高度控制,您可以将DockPanel 替换为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>

这会导致:

如需更深入的讨论,请访问我的博文here。

【讨论】:

@David:别开玩笑了。我发布这个问题是因为谷歌分析告诉我这是我最受欢迎的博客文章之一,所以在 *** 上直接回答这个问题将对社区有益。我的博客上没有广告,所以不要从链接诱饵中获得任何好处。而且我在回答中提供了足够多的信息,除非您想要更多信息,否则您甚至不需要访问我的博客。现在请去寻找一些有建设性的事情做。 谢谢,这就是我要找的东西 嗯,有人知道为什么如果我在 StatusBarItem 中放置一个分隔符,它不会被绘制?谢谢。 需要修复损坏的链接。 你的博客就像我的博客;没有广告和干净的界面,这说明了很多。 :-)【参考方案2】:

实际上,在 Kent 的回复之后,我尝试了这个并且效果很好:

<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>

【讨论】:

我并不是说它不起作用,而是它“混乱且不方便”,因为它的顺序不合逻辑,而且你对布局的控制要少得多。试着让 Set 项占据可用宽度的一半,你就会明白我的意思了。 我认为,如果您了解 DockPanel 的工作原理,这是最简洁的方法。 如果我的状态栏在用户控件中并且该用户控件显示为内容控件停靠在底部的内容控件,则似乎不起作用。【参考方案3】:

只是为了那些阅读上面优秀答案的人的参考,我想提出一些更简单的方法来达到相同的结果。 (既不使用DockPanel 也不使用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>

免责声明:这是很久以前我刚开始使用 WPF 的时候。

【讨论】:

以上是关于如何自定义 WPF 状态栏布局?的主要内容,如果未能解决你的问题,请参考以下文章

自定义状态栏notification布局

C# wpf 如何实现自定义控件,布局时,大小发生变化,内部绘制的曲线跟随变化?

更新自定义导航栏透明图像自动布局 Iphone X?

【WPF】自定义标题栏

WPF:自定义控件布局

WPF的ListView控件自定义布局用法实例