WPF: Drop shadow on borderless window without custom chrome - wpf

Im struggling with drop shadow on WPF-windows with WindowStyle=None and ResizeMode=NoResize. Is there any good alternative to using a DropShadow-effect on the window-content? I have tried WindowChrome in Shell Integration Library but its not showing any "Chrome" when ResizeMode=NoResize.
If it was possible somehow to draw a wpf-drop-shadow outside my window borders it could be a solution. If Im drawing the drop shadow inside the window I get a different behaviour then standard when for instance moving the mouse-cursor over the shadow. There should be no hit testing in my window when doing this and clicking this area should activate the window behind etc.
Zune seem to be drawing its own drop shadow because its not looking exactly like the standard Chrome-shadow. But its behaving like a normal drop shadow in that way its not capturing mouse events. I wonder how they do it.
Spotify also has another kind of shadow which is also not capturing mouse events.
I guess these apps draw their own WindowChrome completely, but how? Is this supported in WPF somehow?
<Window x:Class="ShellIntegrationTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:shell="clr-namespace:Microsoft.Windows.Shell;assembly=Microsoft.Windows.Shell"
Title="MainWindow" Height="512" Width="384" WindowStyle="None" ResizeMode="NoResize">
<shell:WindowChrome.WindowChrome>
<shell:WindowChrome ResizeBorderThickness="5" GlassFrameThickness="-1" CornerRadius="0" CaptionHeight="25" />
</shell:WindowChrome.WindowChrome>
</Window>

This code will work on a borderless window to show the shadow if the window is set to not resize and it's style is none.
xmlns:local="clr-namespace:BorderTest"
mc:Ignorable="d" WindowStyle="None" ResizeMode="NoResize"
Title="MainWindow" Height="350" Width="525" AllowsTransparency="True" Background="Transparent">
<Border Margin="10" BorderThickness="1" BorderBrush="Blue">
<Border.Effect>
<DropShadowEffect Color="Black"
Direction="270"
BlurRadius="10"
ShadowDepth="3" />
</Border.Effect>
<Grid Background="White">
</Grid>
</Border>

If you change ResizeMode to CanResize and set the ResizeBorderThickness to 0, you'll get a borderless window, which cannot be resized and the drop shadow can be clicked through so the window behind it activates.

<Window
.........
.........
.........
Title="Welcome" Loaded="Window_Loaded" Height="400" Width="400" ResizeMode="NoResize" AllowsTransparency="True" WindowStyle="None" ShowInTaskbar="False" WindowStartupLocation="CenterScreen" Background="Transparent" BorderThickness="0">
<Border Margin="10" CornerRadius="100"
BorderBrush="Black"
BorderThickness="1"
CornerRadius="10">
<Border.Effect>
<DropShadowEffect />
</Border.Effect>
<Grid>
...
...//main design inside windows
...
</Grid>
</Border>

Related

WPF window corner radius and shadow

I want to have a window without buttons, with rounded corners and with shadow.
Like this:
So this is my XAML code:
<Window x:Class="Password.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Password"
mc:Ignorable="d"
Title="MainWindow" Height="294" Width="546" Background="Transparent" Foreground="#FFE755DD" AllowsTransparency="True" WindowStyle="None" WindowStartupLocation="CenterScreen">
<Grid >
<Grid.Effect>
<DropShadowEffect BlurRadius="20" Direction="-90" RenderingBias="Quality" ShadowDepth="2"/>
</Grid.Effect>
<Border Background="#FF22173C" CornerRadius="20, 20, 20, 20"/>
</Grid>
</Window>
And this is the output:
The shadow isn't rounded.
What should I do?
The blur gets cropped because your window doesn't own the space around it.
Set <Grid Margin="20"> to allow the blur to occur in the area you control.

WPF Window Not Showing Transparency Correctly

TI'm having some trouble getting my Window to be Transparent.
The Window is defined below:
<Window x:Class="HKC.Desktop.Views.UserInterfaces.RemoteKeypad"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Closing="Window_Close"
KeyDown="RemoteKeypad_KeyDown"
KeyUp="RemoteKeypad_KeyUp" MouseDown="OnMouseDown_Event"
Title="Title" Width="325" Height="370"
ResizeMode="NoResize" WindowStartupLocation="CenterScreen" WindowStyle="None" AllowsTransparency="True" Background="Transparent">
I then have a border defined to give a curved edge to the Window, with a Grid inside for layout purposes:
<Border CornerRadius="20" Background="Transparent" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Border.Effect>
<DropShadowEffect BlurRadius="6" ShadowDepth="3" Color="#484948" />
</Border.Effect>
<Grid Background="Transparent" VerticalAlignment="Stretch">
....
</Grid>
</Border>
</Window>
For some reason, the first time that I open the window the background is not transparent
However, If I click away from the Window, back back on it, the transparency is working as expected.
Turns out the problem was with an external tool for adding Drop Shadows to elements.

Why is my window transparent when using AllowsTransparency="True"

I'm attempting to make a translusent popup that covers the entire screen using WPF. The idea is to effectively create the light box style effect that we all see regularly when using assorted webpages.
The application runs full screen (no option to close, minimise, etc) and replaces the windows shell. Because of this the window needs to stretch to cover the entire of the screen.
The desired effect is to have a new window pop up covering the full screen. This window will have a translucent background with some central content that will be completely opaque. Interaction with the central content will be the only way for the user to interact with the application.
The problem that I am facing is the when AllowsTransparency is set to False the Window is not transparent, as you would expect. But when I set AllowsTransparency="True" then the window and all its contents (including the central content) is completely transparent. The new window, while invisible is there and is stopping any interaction with they system.
Has any one else encountered this problem, of windows not being visible at all when AllowsTransparence="true" is set, or even better found a solution or work around for it?
The xaml for the window is:
<Window x:Class="Views.BorderedPopupView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" Background="{DynamicResource WindowBackground}" AllowsTransparency="True">
<Window.Resources>
<SolidColorBrush x:Key="TranslusentBrush" Opacity="0.1"/>
<SolidColorBrush x:Key="WindowBackground" Color="Transparent"/>
</Window.Resources>
<Viewbox StretchDirection="Both" Stretch="Fill" Margin="5,0,13,-8" >
<Grid Height="768" Width="1024" Background="{StaticResource TranslusentBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"></ColumnDefinition>
<ColumnDefinition Width="6*"></ColumnDefinition>
<ColumnDefinition Width="2*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2*"></RowDefinition>
<RowDefinition Height="6*"></RowDefinition>
<RowDefinition Height="2*"></RowDefinition>
</Grid.RowDefinitions>
<Grid Opacity="1" Grid.Row="1" Grid.Column="1">
<ContentControl x:Name="Popup" Grid.Row="1" Grid.Column="1"/>
</Grid>
</Grid>
</Viewbox>
</Window>
I ran into something similar the other day. For some reason when you set AllowsTransparency="True" you must also specify a Width and a Height for the Window otherwise the whole thing becomes invisible.
I did the same thing you did and also set the WindowState to Maximized but the Window was no where to been seen until I specified a Width and Height.
Your Grid is appearing above your other elements in the z-order, so clicks will be intercepted by it. To turn hit testing off for that Grid, set IsHitTestVisible="false".
If you would not resize your window try set ResizeMode="CanResizeWithGrip" or ResizeMode="NoResize" to window.

Window set to size around content leaves gap on each side

Can someone please tell me why, even though I've set my Window to SizeToContent and my content is Width=40 does the app load bigger across the Width?
The following example sizes to height, but the width is about 100 pixels (estimation).
Thanks
<Window x:Class="WpfApplication2.RetailButs"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="RetailButs" SizeToContent="WidthAndHeight"
WindowStyle="None" MinWidth="0" >
<Grid x:Name="LayoutRooty" Width="40" Height="40">
<Border x:Name="LayoutRootx" Background="White" BorderBrush="Black" CornerRadius="8" BorderThickness="4" >
</Border>
</Grid>
</Window>
The extra size you have got comes from 3 top right window buttons.
So the best solution is just take buttons out (1) and put some minimum size for the window (2).
Try this and it will be exactly what you need.
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Width="40" Height="40" SizeToContent="WidthAndHeight" WindowStyle="None" ResizeMode="NoResize">
<Grid x:Name="LayoutRooty" Width="40" Height="40">
<Border x:Name="LayoutRootx" Background="White" BorderBrush="Black" CornerRadius="8" BorderThickness="4" >
</Border>
</Grid>
</Window>
There was a similar question recently which i was unable to find. The size is that which would be needed if the WindowStyle were the default 3D border with all the buttons which take up a lot of space. I think there is some way to update the layout, maybe you can figure something out.
Edit: Set the window's Width="0" (or any other value for that matter) and it should update correctly. The size to content will override the value.
(If you set the WindowStyle to ToolWindow it always fits correctly)

combine image and solidcolor background for a WPF Form

I have a WPF form that I am building. I want to specify a background image for the window, which is easy enough. However, I also want to specify a color so that the area of the form not covered by the image is white. I've seen some examples that show using two different background brushes, but when I try that VS.NET tells me I can't have multiple brushes.
This is the XAML I'm using
<Window x:Class="Consent.Client.Shell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cal="http://www.codeplex.com/CompositeWPF"
Title="Shell" WindowStyle="None" WindowState="Maximized" FontSize="24">
<Window.Background>
<ImageBrush AlignmentX="Left" AlignmentY="Top" Stretch="None" TileMode="None" ImageSource="logo_header2.png" />
</Window.Background>
<ItemsControl Background="White" VerticalAlignment="Center" cal:RegionManager.RegionName="MainRegion" >
</ItemsControl>
</Window>
This works great for the image, but the background not covered by the image is black. How do I make it white? Changing the image itself is not really an option.
Try this (I removed everything not directly relevant to the question to make the code clearer):
<Window x:Class="Consent.Client.Shell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="White">
<Grid>
<Grid.Background>
<ImageBrush ImageSource="logo_header2.png" />
</Grid.Background>
<ItemsControl>
</ItemsControl>
</Grid>
</Window>
Basically, set the window's background to the behind the image color, than put a grid in the window and give the grid you background image, put everything inside the grid instead of directly in the window.
As an Extension to Nirs answer. If you want to have margins around your content, but let the background image be able to fill the whole window, you can also stack backgrounds using borders:
<Window x:Class="Consent.Client.Shell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="White">
<Border Padding="10">
<Border.Background>
<ImageBrush ImageSource="logo_header2.png" />
</Border.Background>
<!--<Your content >-->
</Border>
</Window>
I'm not sure you can combine brushes. You could play around with ImageBrush, or you could forget the "background" and stack the items on top of each other in a Grid:
<Window x:Class="Consent.Client.Shell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cal="http://www.codeplex.com/CompositeWPF"
Title="Shell" WindowStyle="None" WindowState="Maximized" FontSize="24">
<Grid>
<Image Source="logo_header2.png" Stretch="None" VerticalAlignment="Top" />
<ItemsControl Background="White" VerticalAlignment="Center" cal:RegionManager.RegionName="MainRegion" >
</ItemsControl>
</Grid>
</Window>

Resources