用Viewbox模糊背景 [英] Blur background with Viewbox
问题描述
我正在建立类似于AERO玻璃给您的效果,即模糊的窗户.我很快意识到在WPF中这并不容易,但是我设法使其几乎完全正常工作. 涉及Viewbox时,我只是被卡住了.
i'm building a similar effect which AERO glass gives you, a blurred window. I quickly realized that is not easy in WPF, but i managed to get it to work almost completely. I'm just stuck when a Viewbox is involved.
所以我所做的是:我创建了一个矩形,用可视笔刷获取了给定背景元素的一部分,转换了视图框以获取与矩形重叠的图像的确切空间,并将其用作填充矩形.
So what i did was: I created a rectangle, made a visual brush to take a portion of a given background element, convert the viewbox to take exactly the space of the image that the rectangle overlaps and use that as the fill for the rectangle.
<Grid x:Name="grid">
<Image x:Name="image" Source="someImage.png"/>
<Rectangle x:Name="blurBackgroundRect" Width="100" Height="100">
<Rectangle.Effect>
<BlurEffect Radius="10"/>
</Rectangle.Effect>
<Rectangle.Fill>
<VisualBrush
ViewboxUnits="Absolute"
AlignmentX="Center"
AlignmentY="Center"
Visual="{Binding ElementName=image}"
Stretch="None">
<VisualBrush.Viewbox>
<MultiBinding Converter="{StaticResource visualBrushTargetConverter}">
<Binding ElementName="grid"/>
<Binding ElementName="blurBackgroundRect"/>
<Binding ElementName="grid" Path="ActualWidth"/>
<Binding ElementName="grid" Path="ActualHeight"/>
</MultiBinding>
</VisualBrush.Viewbox>
</VisualBrush>
</Rectangle.Fill>
</Rectangle>
</Grid>
ElementName网格是指矩形和图像的公共父级.我不能使它们成为祖先,否则会干扰模糊效果.因此,我将它们彼此并排放置在网格中.
The ElementName grid, referes to the common parent of my rectangle and my image. I cant make them ancestors, otherwise it would interfere with the blur effect. So i place them next to each other in a grid.
最后一部分是多值转换器,它为VisualBrush Viewbox进行实际计算.
The final part is the Multivalue converter, which does the actual calculation for the VisualBrush Viewbox.
public class VisualBrushTargetConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var parentControl = values[0] as FrameworkElement;
var targetControl = values[1] as FrameworkElement;
var transformedPos = targetControl.TransformToVisual(parentControl).Transform(new Point());
var transformedSize = targetControl.TransformToVisual(parentControl).Transform(new Point(targetControl.RenderSize.Width, targetControl.RenderSize.Height));
transformedSize = new Point(transformedSize.X - transformedPos.X, transformedSize.Y - transformedPos.Y);
return new Rect(transformedPos.X,
transformedPos.Y,
transformedSize.X,
transformedSize.Y);
}
}
因此,这是重现我以下问题的所有必要条件.如果要测试代码,则可以轻松地将其放入简单的wpf应用程序中.
So this is all necessary to reproduce my following problem. If you want to test the code, you can easily place that into a simple wpf application.
如果对此进行测试,您会发现它工作正常.现在,如果我们将矩形放置在Viewbox和固定大小的网格内(模仿我的实际问题),就会出现问题.
If you test this, you see that it works fine. The problem occurs now if we place the rectangle inside a Viewbox and a grid with a fixed size (which mimics my actual problem).
<Image x:Name="image" .../>
<Viewbox>
<Grid Width="800" Height="600">
<Rectangle x:Name="blurBackgroundRect" ...>
</Grid>
</Viewbox>
因此,我猜测是在布局之后应用了来自视图框的缩放比例,因此无法在我的TransformTo调用中识别出来.但是我已经尝试在转换中使用Viewbox的实际缩放比例,但是没有运气.只要有Viewbox,我就无法使其正常工作,所以我希望任何人都知道可能出什么问题,甚至可以为我提供一个更简单的解决方案. 我希望该代码以后能够转换为自定义控件,以轻松地重复使用它,因此我更喜欢在很大程度上不依赖任何特殊条件的方式.
So im guessing that the scaling from the viewbox is applied after the layouting, thus won't get recognized in my TransformTo calls. But i already tried to use the actual scaling of the Viewbox in my convert, but to no luck. As long as the Viewbox is there, i can't get it to work, so i hope anybody has an idea what could be wrong, or maybe even point me to a much simpler solution. I want that code to later convert to a custom control, to easily reuse that, so i prefere ways that don't rely to much on any special conditions.
推荐答案
我能够通过将VisualBrush上的Stretch更改为Fill而不是None来解决怪异的行为.
I was able to fix the weird behaviour by changing the Stretch on the VisualBrush to Fill instead of None.
这篇关于用Viewbox模糊背景的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!