2012-07-17 5 views
3

저는 AERO 유리가 제공하는 것과 비슷한 효과를 내고 있습니다. 흐린 창입니다. WPF에서는 쉽지 않다는 것을 빨리 알았지 만, 거의 완벽하게 작동 할 수있었습니다. 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의 실제 크기 조정을 사용하려고했지만 운이 없었습니다. 뷰 박스가 존재하는 한, 나는 그것을 작동시킬 수 없다. 그래서 누군가는 무엇이 잘못 될 수 있었는지, 아니면 훨씬 더 간단한 해결책을 가르쳐 주길 바란다. 나중에 코드를 사용자 지정 컨트롤로 변환하여 쉽게 다시 사용할 수 있으므로 특정 조건에 많이 의존하지 않는 방법을 선호합니다.

+0

+1 좋은 연구와 완전한 코드를 위해 ... 그리고 'layouting'에 대해서 – Charleh

답변

2

VisualBrush의 Stretch를 None 대신 Fill으로 변경하여 이상한 동작을 수정할 수있었습니다.

+0

Wonderful! 그것은 내가 기대했던 것보다 쉬웠다. 나는 변환기와 뷰 박스에 너무 집중하여 Stretch 매개 변수가 내 마음을 넘어선 적이 없었다. 고마워요! – dowhilefor