.netwpf.net-4.5window-chrome

Rendering "behind" the window chrome control boxes


I've got a style which removes the usual window chrome and replaces it with aero-effect glass (Code at the bottom).

If you look at the indicated line, I'm using a black box to darken the glass but remain semi-transparent (The example I took this from used a White box for a similar purpose). The problem I have is that the black box appears above the control boxes. Screenshots of the window with and without the black box...

enter image description here enter image description here

(Notepad included for reference). I'd like to make the window darker but that would make the controls unusable with my current approach. Also, note how the red glow from hovering over the X is bright outside my form but dark inside it.

So, my specific question is... How can I get the control boxes to render on top of a "background" layer?

More generally, it feels like there must be a better way to do this? I tend to dislike trying to emulate too much as there are far too many edge cases.

What I'm trying to achieve is a window that is (* if it's working now):

I mention that laundry list only so you know what I'm going to need to do with any solution. I'm using .Net 4.5 which means System.Shell.ChromeWindow is included in the framework but seems to be slightly different from the older versions mentioned in every tutorial I can find.

Can someone please point me in the right direction?

<Application.Resources>
    <BitmapImage x:Key="MainIcon"
                 UriSource="./Resources/MainIcon.png" />
    <Style x:Key="Chromeless"
           TargetType="{x:Type Window}">
        <Setter Property="WindowChrome.WindowChrome">
            <Setter.Value>
                <WindowChrome GlassFrameThickness="-1"
                              ResizeBorderThickness="4"
                              CaptionHeight="36" />
            </Setter.Value>
        </Setter>
        <!--pack://application:,,,/Resources/Search.png-->
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Window}">
                    <Grid>
                        <!-- This is the ContentPresenter that displays the window content. -->
                        <Border Margin="0,40,0,25">
                            <ContentPresenter Content="{TemplateBinding Content}" />
                        </Border>

                        <!--This is the transparent white rectangle that goes behind the window content.-->
                        <!-- Window Border Content -->
<!-- HERE ---->             <Border Margin="0"
                                BorderBrush="Gray"
                                BorderThickness="0,1,0,1"
                                Grid.ZIndex="-1">
                            <Rectangle Fill="Black"
                                       Opacity="0.5" />
                        </Border>
                        <!-- System Button -->
                        <Button VerticalAlignment="Top"
                                HorizontalAlignment="Left"
                                Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}"
                                WindowChrome.IsHitTestVisibleInChrome="True"
                                Command="{x:Static SystemCommands.ShowSystemMenuCommand}"
                                CommandParameter="{Binding ElementName=LibraryWindow}"
                                BorderThickness="0">
                            <Image Source="{StaticResource MainIcon}"
                                   Width="64"
                                   Height="64"
                                   WindowChrome.IsHitTestVisibleInChrome="True"
                                   />

                        </Button>
                        <!-- Window Title -->
                        <TextBlock VerticalAlignment="Top"
                                   TextAlignment="Left"
                                   FontSize="15"
                                   Padding="40,8,0,0"
                                   Foreground="White"
                                   Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Title}" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</Application.Resources>

Solution

  • From what I understood, you are trying to darken the entirety of the glass area by rendering a big black rectangle on top of everything, but you want the window control buttons to not be affected. Sadly, that approach does not work because if you use a custom window chrome then you cannot selectively decide what gets rendered on top of or under the glass; it will always render on top. The only way to do this, as far as I know, is to re-implement the buttons, because they are semi transparent, so no matter if you change the colour of the aero glass or just use a rectangle, the buttons will always be affected. This is especially obvious in Windows 10; if you change the aero glass color, the backgrounds of the buttons will change as well, but it is also the same in windows 8, 7, and vista. I guess if you are using Windows XP then you can change the color of the window frame, but otherwise, it is not really possible with the default buttons.