问题描述
我真的很喜欢,可以看到例如在iOS上,其中basicaly看起来像当前视图的顶部绘制的层,bluring视觉内容,并将它作为背景的影响。有没有办法实现WPF类似的东西?
我见过人们主要处理与窗位这个模糊/透明度,但我需要它在窗口中。
$ b $ ; b让我们说这是我的窗口内容
< StackPanel中的HorizontalAlignment =中心方向=横向>
<图像源=包://应用:,,, /资源/ Penguins.jpg/>
<图像源=包://应用:,,, /资源/ Penguins.jpg/>
< / StackPanel的>
看起来像
而现在我想上画点什么最重要的是(而不是使用红色背景),这blures无论是它的下面,并使用它作为背景,保持它的内容不是blurY的。
< DockPanel中保证金=15背景=红>
< StackPanel的方向=横向VerticalAlignment =中心的HorizontalAlignment =中心>
<标签内容=某些标签/>
<文本框宽度=100HEIGHT =20/>
< / StackPanel的>
< / DockPanel中>
结果:
-
我们将使用一个网格的层次感。背景:您的应用程序主要内容。前景:你的伪对话框,将有一个模糊的背景
-
我们将把背景边框和它的名字引用这条边界。
-
这将在
的VisualBrush
使用,并为我们将要模糊图像。前景也将是一个分层网格。背景:一个矩形,填充用刷子和使用模糊效果。前景:无论你想在前面
-
添加一个引用到
System.Windows.Interactivity
-
添加以下行为的代码:
使用系统;
使用System.Collections.Generic;
使用System.Linq的;使用System.Windows
;使用System.Windows.Controls的
;
使用System.Windows.Data;
使用System.Windows.Interactivity;使用System.Windows.Media
;使用System.Windows.Media.Effects
;使用System.Windows.Shapes
;
命名空间WpfApplication1
{
公共类BlurBackgroundBehavior:行为<形状和GT;
{
公共静态只读的DependencyProperty BlurContainerProperty
= DependencyProperty.Register(
BlurContainer,
typeof运算(的UIElement),
typeof运算(BlurBackgroundBehavior),
新PropertyMetadata(OnContainerChanged));
私人静态只读的DependencyProperty BrushProperty
= DependencyProperty.Register(
刷,
typeof运算(的VisualBrush),
typeof运算(BlurBackgroundBehavior),
新PropertyMetadata());
私人的VisualBrush刷
{
{返回(的VisualBrush)this.GetValue(BrushProperty); }
集合{this.SetValue(BrushProperty,值); }
}
公众的UIElement BlurContainer
{
{返回(的UIElement)this.GetValue(BlurContainerProperty); }
集合{this.SetValue(BlurContainerProperty,值); }
}
保护覆盖无效OnAttached()
{
this.AssociatedObject.Effect =新BlurEffect
{
半径= 80,
KernelType = KernelType.Gaussian,
RenderingBias = RenderingBias.Quality
};
this.AssociatedObject.SetBinding(Shape.FillProperty,
新的Binding
{
来源=此,
路径=新的PropertyPath(BrushProperty)
});
this.AssociatedObject.LayoutUpdated + =(发件人,参数)=> this.UpdateBounds();
this.UpdateBounds();
}
保护覆盖无效OnDetaching()
{
BindingOperations.ClearBinding(this.AssociatedObject,Border.BackgroundProperty);
}
私有静态无效OnContainerChanged(DependencyObject的D,DependencyPropertyChangedEventArgs E)
{
((BlurBackgroundBehavior)D).OnContainerChanged((的UIElement)e.OldValue,(的UIElement)e.NewValue);
}
私人无效OnContainerChanged(的UIElement属性oldValue,的UIElement newValue)以
{
如果(属性oldValue!= NULL)
{
属性oldValue。 LayoutUpdated - = this.OnContainerLayoutUpdated;
}
如果(为newValue!= NULL)
{
this.Brush =新的VisualBrush(newValue)以
{
ViewboxUnits = BrushMappingMode .Absolute
};
newValue.LayoutUpdated + = this.OnContainerLayoutUpdated;
this.UpdateBounds();
}
,否则
{
this.Brush = NULL;
}
}
私人无效OnContainerLayoutUpdated(对象发件人,EventArgs EventArgs的)
{
this.UpdateBounds();
}
私人无效UpdateBounds()
{
如果(this.AssociatedObject = NULL&放大器;!&安培; this.BlurContainer = NULL&放大器;!&安培;这.Brush = NULL)
{
点差= this.AssociatedObject.TranslatePoint(新点(),this.BlurContainer)!;
this.Brush.Viewbox =新的矩形(差值,this.AssociatedObject.RenderSize);
}
}
}
}
-
使用它在XAML是这样的:
<网格和GT;
< BORDER X:NAME =内容>
< Border.Background>
<的ImageBrush的ImageSource =bild1.jpg/>
< /Border.Background>
<&StackPanel的GT;
<文本框宽度=200保证金=10/>
<文本框宽度=200保证金=10/>
<文本框宽度=200保证金=10/>
< / StackPanel的>
< /边框>
<电网保证金=59,63,46,110>
<矩形ClipToBounds =真>
< I:Interaction.Behaviors>
< wpfApplication1:BlurBackgroundBehavior BlurContainer ={绑定的ElementName =内容}/>
< /我:Interaction.Behaviors>
< /矩形>
<文本框VerticalAlignment =中心文本=嗒嗒WIDTH =200HEIGHT =30/>
< /网格和GT;
< /网格和GT;
-
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>
这篇关于与模糊效果分层窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!