AEROガラスが提供するのと同様の効果、ぼやけたウィンドウを構築しています。これはWPFでは簡単ではないことにすぐに気付きましたが、ほぼ完全に機能させることができました。ビューボックスが関係しているときに私は立ち往生しています。
つまり、長方形を作成し、視覚的なブラシを作成して特定の背景要素の一部を取得し、ビューボックスを変換して、長方形が重なる画像のスペースを正確に取得し、それを長方形の塗りつぶしとして使用しました。
<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ビューボックスの実際の計算を行うMultivalueコンバーターです。
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アプリケーションに簡単に配置できます。
これをテストすると、正常に機能していることがわかります。ビューボックス内に長方形を配置し、固定サイズのグリッドを配置すると、問題が発生します(これは私の実際の問題を模倣しています)。
<Image x:Name="image" .../>
<Viewbox>
<Grid Width="800" Height="600">
<Rectangle x:Name="blurBackgroundRect" ...>
</Grid>
</Viewbox>
したがって、ビューボックスからのスケーリングはレイアウト後に適用されると推測しているため、TransformTo呼び出しでは認識されません。しかし、私はすでに変換でビューボックスの実際のスケーリングを使用しようとしましたが、運がありませんでした。ビューボックスがそこにある限り、私はそれを機能させることができないので、誰かが何が間違っている可能性があるのかを知っているか、もっと簡単な解決策を教えてくれることを願っています。そのコードを後でカスタムコントロールに変換して、それを簡単に再利用できるようにしたいので、特別な条件にあまり依存しない方法を好みます。