首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Viewbox模糊背景

使用Viewbox模糊背景
EN

Stack Overflow用户
提问于 2012-07-17 22:35:31
回答 1查看 1.7K关注 0票数 4

我正在构建一个类似于AERO玻璃给你的效果,一个模糊的窗口。我很快意识到这在WPF中并不容易,但我设法让它几乎完全工作。当涉及到Viewbox时,我只是卡住了。

所以我所做的是:我创建了一个矩形,制作了一个视觉画笔来获取给定背景元素的一部分,转换viewbox以获取矩形重叠的图像空间,并将其用作矩形的填充。

代码语言:javascript
复制
<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网格,引用我的矩形和图像的共同父元素。我不能让它们成为祖先,否则会影响模糊效果。所以我把它们放在一个网格里一个接一个。

最后一部分是多值转换器,它执行VisualBrush Viewbox的实际计算。

代码语言:javascript
复制
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应用程序中。

如果您测试它,您会发现它工作得很好。如果我们将矩形放在一个Viewbox和一个固定大小的网格中(这模仿了我的实际问题),现在问题就出现了。

代码语言:javascript
复制
<Image x:Name="image" .../>
<Viewbox>
    <Grid Width="800" Height="600">
        <Rectangle x:Name="blurBackgroundRect" ...>
    </Grid>
</Viewbox>

所以我猜viewbox的缩放是在布局之后应用的,因此在我的TransformTo调用中不会被识别。但我已经尝试在我的convert中使用Viewbox的实际缩放,但没有成功。只要Viewbox在那里,我就不能让它工作,所以我希望有人知道哪里可能是错误的,或者甚至可以给我一个更简单的解决方案。我希望稍后将代码转换为自定义控件,以便轻松重用,因此我更喜欢不太依赖于任何特殊条件的方法。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-07-18 09:57:09

我能够通过将VisualBrush上的拉伸更改为Fill而不是None来修复奇怪的行为。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11524863

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档