2012-07-17 137 views
3

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

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

<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进行实际计算。

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和一个固定大小的网格(模仿我的实际问题)中,现在就会出现问题。

<Image x:Name="image" .../> 
<Viewbox> 
    <Grid Width="800" Height="600"> 
     <Rectangle x:Name="blurBackgroundRect" ...> 
    </Grid> 
</Viewbox> 

所以即时猜测,从视框的缩放的布点之后应用,因而不会在我TransformTo电话得到认可。但我已经尝试在我的转换中使用Viewbox的实际缩放比例,但是没有运气。只要Viewbox在那里,我不能得到它的工作,所以我希望任何人有一个想法是什么可能是错的,或者甚至可以指向我一个更简单的解决方案。 我希望该代码稍后转换为自定义控件,以便轻松地重用该代码,所以我优先考虑不依赖于任何特殊条件的方式。

+0

+1为良好的研究和完整的代码...和'布局'字样 – Charleh 2012-07-17 14:38:05

回答

2

我能够通过更改VisualBrush上的Stretch而不是None来修复怪异行为。

+0

太棒了!这比我希望的容易。我非常专注于转换器和视图框,Stretch参数甚至没有超出我的想象。非常感谢你! – dowhilefor 2012-07-18 09:41:04