使用 WindowChrome 在 WPF Window 上显示默认 window 按钮

Show default window buttons on WPF Window using WindowChrome

我发现在 WPF Window 上使用 WindowChrome 可以让我将内容放在 Window 中我想要的任何位置,这是一个很棒的想法。现在我终于可以使标题栏与我的应用程序的其余部分具有相同的颜色。

但是,我仍然喜欢出现在非样式 Window 上的默认 minimize/maximize/close 按钮。

有什么方法可以让我使用 WindowChrome 设置我的 Window 样式,同时仍然保留默认按钮?

<Style x:Key="MainWindow" TargetType="{x:Type Window}">
    <Setter Property="WindowChrome.WindowChrome">
        <Setter.Value>
            <WindowChrome CaptionHeight="30" ResizeBorderThickness="5" />
        </Setter.Value>
    </Setter>
</Style>

<Window Style="{StaticResource MainWindow}">
    <Grid Background="Black">
        <MyContent />
    </Grid>
</Window>

这使得一个大黑 window(太棒了!)但是没有任何 min/max/close 按钮,因为它们隐藏在 Grid 后面(不太好)。不过,这些按钮仍然可以点击,所以它们显然就在那里。

在引入 Windows 10 之前,您可以通过在外部 Border 添加 Margin 属性 来自定义 Window.Template。就像下面的代码。

<Window.Template>
    <ControlTemplate TargetType="Window">
        <Border Background="#3FFFFFFF">
            <AdornerDecorator Margin="8 10 8 8">
                <Border>
                    <ContentPresenter/>
                </Border>
            </AdornerDecorator>
        </Border>
    </ControlTemplate>
</Window.Template>
<WindowChrome.WindowChrome>
    <WindowChrome UseAeroCaptionButtons="True" GlassFrameThickness="8 30 8 8"/>
</WindowChrome.WindowChrome>

上面的代码做了这些事情:

  1. 使用 WindowChrome 使我们的控件显示在 windows none 客户区上方。
  2. 避免我们的控件覆盖 window 字幕按钮。
  3. 如果您想在标题栏上方显示一些控件,请将其 Margin 属性 设置为负数,例如 0 -30 0 0.

但在 Windows 10 之后,尤其是 Windows 10 Creators Update 之后,您将无法再显示具有可接受的 window 样式的 windows 默认按钮。它总是显示一个主题边框,丑陋!

<WindowChrome NonClientFrameEdges="Left,Bottom,Right" UseAeroCaptionButtons="True" GlassFrameThickness="8 30 8 8"/>

上面的代码可能适用于 Windows10 的早期版本。我的意思是,不像 Creators Update 上的那样难看。

Is there any way I can style my Window using WindowChrome yet still preserve the default buttons?

不,我不这么认为。您可以将 GlassFrameThickness 属性 设置为 0 以禁用按钮,恐怕您将不得不创建自己的自定义按钮。您可以参考以下项目的一些示例:https://wpfwindow.codeplex.com/.

如果您想要 Window 10 种样式的标题按钮,您可以使用 Segoe MDL2 Assets 字体系列:

<Style x:Key="CaptionButtonStyle" TargetType="Button">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid x:Name="LayoutRoot" Background="Transparent" Width="44" Height="30">
                    <TextBlock x:Name="txt" Text="{TemplateBinding Content}" FontFamily="Segoe MDL2 Assets" FontSize="10" 
                                   Foreground="#999999" HorizontalAlignment="Center" VerticalAlignment="Center"
                                   RenderOptions.ClearTypeHint="Auto" TextOptions.TextRenderingMode="Aliased"  TextOptions.TextFormattingMode="Display"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="LayoutRoot" Property="Background" Value="#E5E5E5"/>
                        <Setter TargetName="txt" Property="Foreground" Value="#000000"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style x:Key="MinimizeButtonStyle" TargetType="Button" BasedOn="{StaticResource CaptionButtonStyle}">
    <Setter Property="Content" Value="&#xE949;"/>
</Style>

<Style x:Key="MaximizeButtonStyle" TargetType="Button" BasedOn="{StaticResource CaptionButtonStyle}">
    <Setter Property="Content" Value="&#xE739;"/>
</Style>

<Style x:Key="RestoreButtonStyle" TargetType="Button" BasedOn="{StaticResource CaptionButtonStyle}">
    <Setter Property="Content" Value="&#xE923;"/>
</Style>