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.
Related
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
This should be easy but I'm blanking out here.
I have a TextBlock inside of a Border control. The Width of the Border changes based on the length of the text in the TextBlock (updated in ViewModel). I would like this change in Width to be animated so that the width grows slowly (instead of jerky).
My Xaml:
<Border x:Name="myBorder" BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" VerticalAlignment="Top">
<TextBlock x:Name="myTextBlock" HorizontalAlignment="Left" Text="Some Text"/>
</Border>
This is a perfect job for Expression Blend. You will need to create a Storyboard animation. Then once its created go into the code behind in visual studios and play it. You can tell it to play to a certain point based on how much text you have in your text block.
Here is a basic tutorial
http://www.silverlightbuzz.com/2009/10/12/animating-with-storyboards-in-blend/
This example has back end code also
http://dotnet.dzone.com/articles/wpf-storyboard-%E2%80%93-what-it-and
How do I add the Aero white glow behind a control in WPF?
I mean the glow like in a window's caption bar in Vista/7.
This unrelated question seems to have the answer...
Outer bevel effect on text in WPF
I just needed a rectangle behind my text block...
<Rectangle Height="{Binding ElementName=textBlock1, Path=ActualHeight}" HorizontalAlignment="{Binding ElementName=textBlock1, Path=HorizontalAlignment}" Margin="{Binding ElementName=textBlock1, Path=Margin}" VerticalAlignment="{Binding ElementName=textBlock1, Path=VerticalAlignment}" Width="{Binding ElementName=textBlock1, Path=ActualWidth}" Fill="White" Opacity="0.5">
<Rectangle.Stroke>
<SolidColorBrush />
</Rectangle.Stroke>
<Rectangle.Effect>
<BlurEffect Radius="10" KernelType="Gaussian" />
</Rectangle.Effect>
</Rectangle>
This is gonna do the trick for any control when you replace all the "textBlock"s in the code!
And it looks exactly the same as the aero glow!
Does this help? The effect can be quite subtle but it does look alright.
I tried messing about with Pixel Shaders in WPF using Shazzam but it was a lot of work to achieve the same effect or better. They use a lot of "under the hood" stuff (such as double-pass shaders) of which the techniques aren't available to the WPF api.
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>
I changed the ControrTemplate of a button, gave it a border with CornerRadius and BevelBitmpaEffect. Looks decent enough for the minimal effort. Put it on a colored background and then the problem becomes apperent.
The corner where the lightangle is coming from there is a white snip with a right angle corner. Possibly coming from the light effect but very obvious with a cornerRadius. I don't suppose I could do anything about it ( aside from the obvious like not using a cornerRadius )?
EDIT:
This code should generate the same problem for you
<Style x:Key="TabButtons" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border CornerRadius="8"
SnapsToDevicePixels="True"
Name="BtnBorder"
Width="80"
Height="35"
BorderThickness="1"
BorderBrush="DarkBlue">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="LightBlue" Offset="0" />
<GradientStop Color="DarkBlue" Offset="1" />
</LinearGradientBrush>
</Border.Background>
<Border.BitmapEffect>
<BevelBitmapEffect BevelWidth="5"
EdgeProfile="CurvedOut"
LightAngle="135"
Relief="0.1"
Smoothness="1" />
</Border.BitmapEffect>
<ContentPresenter Name="BtnContent" VerticalAlignment="Center" HorizontalAlignment="Center" ContentSource="Content" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Use this button on a LightBlue Background for example
<Border Background="LightBlue" >
<Button Style={StaticResource TabButtons} >Test</Button>
</Border>
I can't imagine what the problem exactly looks like, but here is one suggestion - try setting the SnapsToDevicePixels to true for the affected button or perhaps the entire window.
The problem might stem from the fact that WPF by default wants to do device independent rendering. Which causes control edges to slightly "bleed" to adjacent pixels due to width/height and DPI/pixels not aligning exactly. Setting SnapsToDevicePixels to true, will force WPF to render exactly for the device pixels and the "bleeding" effect will dissapear...
EDIT:
I tried out the code you provided and I guess the "white snip" is the white(ish) pixels around the corners?
Well the problem here stems from antialiasing, which also lightens the pixels inside the corners. Because you use a dark tone, those lighter pixels stand out and the button doesn't look so nice.
I'm not sure if this can be considered a bug. You would think that antialising will do it's magic on the pixels that make up the corner and outside of the corner, but every pixel inside of the corner should be colored with the background color.
Then again this might be by design, that antialiasing has to mess with the pixels inside the corner as well otherwise you don't get the required effect...
Anyway there are two workarounds:
1) Give the border the following property RenderOptions.EdgeMode="Aliased". This will turn off antialiasing (0% white(ish) pixels), but the controll will look very jaggedy.
2) Use two borders. The outer border will be defined just like you have defined your current border, only set the Background property to just DarkBlue. Then for this outer border create another border as a child element. For this inner border set CornerRadius=7, RenderOptions.EdgeMode="Aliased" and define the Background with the LinearGradientBrush. The inner border will contain the ContentPresenter. The code will look like this:
<Border CornerRadius=8 Background=DarkBlue>
<Border CornerRadius=7 RenderOptions.EdgeMode="Aliased">
<Border.Background>
...
</Border.Background>
<ContentPresenter />
</Border>
</Border>
It won't get rid of the white pixels a 100%, but this is the best compromise I think. With the naked eye I couldn't see any white pixels, but when I zoomed in with the magnifier tool I counted only 2 pixels per corner and only at the bottom corners. Before it was something like 8 pixels per corner. At least the outer border is still antialiased and the control doesn't look jaggedy.
The BevelBitmapEffect didn't make any difference to the appearance of the control so I just ommited it.