wpf: custom window drop shadow - wpf

I'm working on a c# wpf app with a custom window (allowtransparency = true, resize = none, window style = none).
Now I would like to add drop shadow similar to the zune pc software. I read up on this and the included dropshadoweffect is not covering all angles of my window and it is said to kill performance.
I want to implement it like this: I add a margin to my layout grid which I programmatically remove when maximizing the app.
What is the best way to add a drop shadow which can be applied to a grid, which doesn't kill performance and drops shadow in all directions?

I've tried the solutions posted here but none of them were getting me close to the end result which I wanted (See screenshot below). So I tried out a couple of different things and I am posting my solution here, just in case someone would be interested in achieving something similar. BTW: if you could improve my solution, please do let me know because I find it a bit redundant at the moment.
Ok now for the code that drives this effect:
<Window ...
WindowStyle="None" AllowsTransparency="True" Background="Transparent"
...>
<Border>
<Border.Effect>
// opacity does not need to be specified but it looks cooler when you do
<DropShadowEffect BlurRadius="20" ShadowDepth="0" Opacity="0.8"
Color="Blue" />
</Border.Effect>
// make sure the value for Grid Margin is the same as DropShadowEffect
// BlurRadius
<Grid Background="White" Margin="20">
// I tried setting borderthickness and borderbrush to the previous
// <Border> element but instead of the border being shown right after
// the grid and before the drop shadow, it would show after the drop
// shadow making the overall effect very ugly
<Border BorderThickness="1" BorderBrush="Black">
// now you can specify whatever you want to display in the window
<Grid>
....
</Grid>
</Border>
</Grid>
</Window>

DropShadowEffect doesn't "kill performance"... it is rendered using hardware acceleration, and rendering a drop shadow on a window is not a big deal for current GPUs. You're probably confusing with DropShadowBitmapEffect, which is software rendered. Anyway all BitmapEffects were made obsolete in 3.5 SP1 and don't work at all in 4.0, only Effects can be used now

Direction of -75, ShadowDepth of 2 and BlurRadius of 27 helped for me.
Best way is to use blend for doing these.
HTH

Building off of Princes's code, I wanted to paste a final product.
<Window x:Class="RDNScoreboard.Views.InitialWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="InitialWindow" Height="300" Width="300"
WindowStyle="None"
AllowsTransparency="True" Background="Transparent"
BorderThickness="3" >
<Border>
<Border.Effect>
<DropShadowEffect BlurRadius="27" Color="Black" Opacity="0.8" ShadowDepth="2" Direction="-75" />
</Border.Effect>
<Grid Background="White" >
</Grid>
</Border>

Related

WPF Border partially not showing when I set a margin

I'm trying to make a WPF application and was trying to make a square border. I want it to be 10 pixels away from the top, bottom and right edges of the grid. I tried messing with the XAML code but that just produced all sorts of malformations, so I used Visual Studio's Properties tab instead. If I set the right and bottom border to 0 it looks fine, but it covers the edge like this. Code:
<Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Right" Height="180" Margin="604,10,0,0" VerticalAlignment="Bottom" Width="180"/>
If I however add a 10 border to right and bottom (which is what I've used in my previous WPF apps so far) this happens. Code:
<Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Right" Height="180" Margin="604,10,10,10" VerticalAlignment="Bottom" Width="180"/>
They both looks the same in the preview btw. Also sorry, I can't post direct images yet, since I don't have enough reputation.
The reason why the left border is not visible is because of the 604 as the left margin set that to 0 and you should be all good.
<Border BorderBrush="Black" BorderThickness="1" Height="180" Width="180" Margin="0,10,10,10" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
That being said, I do not recommend using fixed Height and Width in your XAML UI.
I've already got a few answers on this so feel free to check them out:
Adaptive UI with XAML
Checkout the Good practices section of this answer

Placing a shadow over a WindowsFormsHost?

I have a WPF grid docked next to a RichTextBox hosted inside a WindowsFormsHost. The grid has a shadow that overlays the WindowsFormsHost, however, it's not showing over the WindowsFormsHost.
Is this a generic issue with hosting Windows Forms controls or is there a workaround?
Thanks in advance.
<WindowsFormsHost x:Name="WinFormsHost" Focusable="True" Background="White"/>
<Grid Background="White">
<Grid.Effect>
<DropShadowEffect Direction="90" Color="#FFC3C3C3" BlurRadius="15" Opacity="0.2"/>
</Grid.Effect>
</Grid>
WindowsFormsHost operates at the highest z-index and cannot be overridden. It's an old issue called the "airspace problem". Unfortunately there is no workaround.

Set layout to have 100% width and 100% height

How can I set a layout to have 100% width and 100% height?
I want my Silverlight application to stretch in the browser to fill all space.
I am using Expression Blend 4.
Here is my XAML:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="RichardKnopNew.MainPage"
Width="960" Height="540">
<Grid x:Name="LayoutRoot" Width="960" Height="540">
<Grid.Background>
<ImageBrush Stretch="Fill" ImageSource="/bg.jpg"/>
</Grid.Background>
<Rectangle Fill="#FF252525" Stroke="Black" Opacity="0.7" RadiusX="10" RadiusY="10" Margin="25,115,335,25" StrokeThickness="0" Height="400"/>
</Grid>
</UserControl>
Your application should do this automatically. The only reasons why it would not do so are:
You've constrained the size of the Silverlight object in the HTML page that hosts the application, or
You've explicitly set the width/height of the MainPage object in MainPage.xaml.
Setting the Background property of the MainPage object to a non-white colour should demonstrate this. If not, please include more details (including the XAML you are using).
Hope this helps...
Chris

Double Border with a VisualBrush in WPF

I'm curious if anyone knows of a way to easily get a double border effect in WPF similar to what you see in the selected items in Windows Explorer in Windows 7.
If you look closely, you'll notice that the selected item has a dark border, a lighter, inner-border, and then a gradient background.
Currently, I'm using two borders around an object any time I want to achieve this effect. Doing it that way is ugly syntactically and really muddies my view xaml. Being a web developer at heart I'd like to separate the xaml structure from the style as much as possible. So, I've started putting this into Styles and Content Templates in order to pull it out of my view xaml.
However, I'm curious if there may be a better way to go about this.
I played around for a while using a VisualBrush as a background to try to get the effect. However, I want to be able to apply the background to elements that can be any size and the way the VisualBrush stretched the visual to fit the element background didn't work the way I wanted it to. Essentially, I'd really just like it to stretch the visual the way the WPF layout system would do it.
Any ideas would be greatly appreciated.
--
Dusty
A VisualBrush is probably not what you want to do in this scenario, as it's pretty heavy.
You can solve the problem with some Xaml without nesting borders.
For example,
<Border BorderBrush="#FF00B5C5" BorderThickness="1" CornerRadius="2" Background="White">
<Grid Background="#FF00B5C5" Margin="1">
<Rectangle Fill="#FFA2F2FE" />
<TextBlock Text="This is some text" VerticalAlignment="Center"/>
</Grid>
</Border>
You can, of course, tweak the properties to get the look you need.
EDIT: If you want to create a style, so you can reskin the look-and-feel, you can do something like this:
<Window.Resources>
<Style x:Key="BorderedTextBlock" TargetType="ContentControl">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Border BorderBrush="#FF00B5C5" BorderThickness="1" CornerRadius="2" Background="White">
<Grid Background="#FF00B5C5" Margin="1">
<Rectangle Fill="#FFA2F2FE" />
<TextBlock Text="{Binding}" VerticalAlignment="Center"/>
</Grid>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<ContentControl Style="{StaticResource BorderedTextBlock}" Content="This is some text" Width="200" Height="24"/>
</Grid>
Additionally, turn this into a custom control with all the styling and theming parameters that you need.
Hope that helps,
Sergio

blurred opacity

I need to create a transparent blurred background. Lets suppose I have a border with a white blurry transparent background. Everything that is behind the border is blurred.
I'm trying to avoid dependencies; I'm currently using .NET 3.0, and want it to run with XP too.
Mockup image:
A VisualBrush can be used to get close to what you want, but has some limitations.
As long as you only need the glass effect within the window (and not be an effect over other windows) and that the placement of the glass effect border is controlled tightly then you could you something like this:-
<Grid>
<Border x:Name="src" Background="Silver">
<Label HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="50">Hello World</Label>
</Border>
<Border Background="White" Margin="40" >
<Border Opacity="0.5" >
<Border.Effect>
<BlurEffect Radius="10"/>
</Border.Effect>
<Border.Background>
<VisualBrush Visual="{Binding ElementName=src}" Stretch="None" />
</Border.Background>
</Border>
</Border>
</Grid>
I don't think that a child element within the visual tree is able to get the VisualBrush of it's parent so this might be a limitation for you. (i.e. the glass panel cannot be contained by the background panel)
I've used VisualBrushes many times usually with TranslateTransforms to move them around a bit to get the right image in the right place.
Update:
Altered XAML to use Effect and not BitmapEffect that is slower and now depreciated as mentioned in the comments below by Steven Robbins.
I would imagine you will need use an Effect for this, applied to a background rectangle or grid.
There's a decent library of effects here if that floats your boat.
Use Vista glass.

Resources