我非常喜欢可以在iOS中看到的效果,其基本上看起来像是在当前视图顶部绘制的图层,使视觉内容模糊并将其用作背景。有没有办法在WPF中实现类似的东西?
我看到人们主要在窗口级别处理这种模糊/透明度,但我需要在窗口内。
我们说这是我窗口的内容。
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<Image Source="pack://application:,,,/Resources/Penguins.jpg"/>
<Image Source="pack://application:,,,/Resources/Penguins.jpg"/>
</StackPanel>
看起来像
现在我想在其上面绘制一些东西(而不是使用红色背景),在它下面的任何地方使用它并将其用作背景,保持它的内容不是blury。
<DockPanel Margin="15" Background="Red">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
<Label Content="Some label"/>
<TextBox Width="100" Height="20"/>
</StackPanel>
</DockPanel>
答案 0 :(得分:4)
<强>结果:强>
我们将在网格中使用分层。背景:您的主要应用内容。前景:您的伪对话框背景模糊。
我们将背景放在边框中,并通过其名称引用此边框。这将在VisualBrush
中使用,并提供我们的模糊图像。
前景也是分层网格。背景:一个矩形,用画笔填充并使用模糊效果。前景:无论你想成为什么样的人。
添加对System.Windows.Interactivity
。
添加以下行为代码:
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);
}
}
}
}
在XAML中使用它,如下所示:
<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>