I really like the effect that can be seen for example in iOS, which basicaly looks like a layer drawn on top of current view , bluring the visual content and using that as a background. Is there a way to achieve something like that in WPF?
I've seen people mostly dealing with this blur/transparency on Window level, but I need it within the window.
Let's say this is the content of my window.
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<Image Source="pack://application:,,,/Resources/Penguins.jpg"/>
<Image Source="pack://application:,,,/Resources/Penguins.jpg"/>
</StackPanel>
Which looks like
And now I'd like to draw something on top of that which ( instead of using red background ) blures whatever is beneath it and uses it as background, keeping it's content not blury.
<DockPanel Margin="15" Background="Red">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
<Label Content="Some label"/>
<TextBox Width="100" Height="20"/>
</StackPanel>
</DockPanel>
Result:
We will use layering in a Grid. Background: Your main application content. Foreground: Your pseudo-dialog that will have a blurred background.
We will put the background in a border and refer to this border by its name. This will be used in a
VisualBrush
and provide our to-be-blurred image.The foreground will also be a layered grid. Background: A rectangle, filled with the brush and using a blur effect. Foreground: Whatever you want to be in front.
Add a reference to
System.Windows.Interactivity
.Add the following behavior code:
using System; using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Interactivity; using System.Windows.Media; using System.Windows.Media.Effects; using System.Windows.Shapes; namespace WpfApplication1 { public class BlurBackgroundBehavior : Behavior<Shape> { public static readonly DependencyProperty BlurContainerProperty = DependencyProperty.Register( "BlurContainer", typeof (UIElement), typeof (BlurBackgroundBehavior), new PropertyMetadata(OnContainerChanged)); private static readonly DependencyProperty BrushProperty = DependencyProperty.Register( "Brush", typeof (VisualBrush), typeof (BlurBackgroundBehavior), new PropertyMetadata()); private VisualBrush Brush { get { return (VisualBrush) this.GetValue(BrushProperty); } set { this.SetValue(BrushProperty, value); } } public UIElement BlurContainer { get { return (UIElement) this.GetValue(BlurContainerProperty); } set { this.SetValue(BlurContainerProperty, value); } } protected override void OnAttached() { this.AssociatedObject.Effect = new BlurEffect { Radius = 80, KernelType = KernelType.Gaussian, RenderingBias = RenderingBias.Quality }; this.AssociatedObject.SetBinding(Shape.FillProperty, new Binding { Source = this, Path = new PropertyPath(BrushProperty) }); this.AssociatedObject.LayoutUpdated += (sender, args) => this.UpdateBounds(); this.UpdateBounds(); } protected override void OnDetaching() { BindingOperations.ClearBinding(this.AssociatedObject, Border.BackgroundProperty); } private static void OnContainerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((BlurBackgroundBehavior) d).OnContainerChanged((UIElement) e.OldValue, (UIElement) e.NewValue); } private void OnContainerChanged(UIElement oldValue, UIElement newValue) { if (oldValue != null) { oldValue.LayoutUpdated -= this.OnContainerLayoutUpdated; } if (newValue != null) { this.Brush = new VisualBrush(newValue) { ViewboxUnits = BrushMappingMode.Absolute }; newValue.LayoutUpdated += this.OnContainerLayoutUpdated; this.UpdateBounds(); } else { this.Brush = null; } } private void OnContainerLayoutUpdated(object sender, EventArgs eventArgs) { this.UpdateBounds(); } private void UpdateBounds() { if (this.AssociatedObject != null && this.BlurContainer != null && this.Brush != null) { Point difference = this.AssociatedObject.TranslatePoint(new Point(), this.BlurContainer); this.Brush.Viewbox = new Rect(difference, this.AssociatedObject.RenderSize); } } } }
Use it in XAML like this:
<Grid> <Border x:Name="content"> <Border.Background> <ImageBrush ImageSource="bild1.jpg" /> </Border.Background> <StackPanel> <TextBox Width="200" Margin="10" /> <TextBox Width="200" Margin="10" /> <TextBox Width="200" Margin="10" /> </StackPanel> </Border> <Grid Margin="59,63,46,110"> <Rectangle ClipToBounds="True"> <i:Interaction.Behaviors> <wpfApplication1:BlurBackgroundBehavior BlurContainer="{Binding ElementName=content}" /> </i:Interaction.Behaviors> </Rectangle> <TextBox VerticalAlignment="Center" Text="Blah" Width="200" Height="30" /> </Grid> </Grid>
来源:https://stackoverflow.com/questions/27432466/layered-window-with-blur-effect