2012-07-17 132 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