Ostatnio potrzebowałem użyć Border z CornerRadius ustawionym na jakąś wartość, aby móc potem umieścić w środku inne kontrolki (np. obrazek). Moje pierwsze podejście było następujące:
<Border CornerRadius="50" BorderBrush="Black" BorderThickness="2"> <Image Stretch="Fill" Source="http://i.zdnet.com/blogs/win7-wallpaper-small.png"></Image> </Border>
Niestety w taki sposób zawartość Border nie zostanie poprawnie przycięta i efekt jest następujący:
Znalazłem na forum bardzo ciekawe rozwiązanie z użyciem OpacityMask. Najpierw kod a potem wyjaśnienie:
<Border CornerRadius="50" BorderBrush="Black" BorderThickness="2"> <Grid> <Border CornerRadius="50" Background="White" BorderThickness="2" x:Name="mask"/> <Image Stretch="Fill" Source="http://i.zdnet.com/blogs/win7-wallpaper-small.png"> <Image.OpacityMask> <VisualBrush Visual="{Binding ElementName=mask}"></VisualBrush> </Image.OpacityMask> </Image> </Grid> </Border>
Efekt:
Aby zrozumieć powyższy kod należy najpierw wyjaśnić jak działa OpacityMask. OpacityMask to brush, który określa, co na docelowym obrazku będzie wyświetlone. Myślę, że poniższy obrazek z MSDN jest doskonałym wyjaśnieniem:
Innymi słowy, OpacityMask służy do ustawiania przezroczystości poszczególnych pikseli.
W naszym przypadku korzystamy z VisualBrush, który wygeneruje pędzel na podstawie innej kontrolki. Stworzyliśmy drugą kontrolkę border jako maskę. Posiada ona ten sam CornerRadius, co oznacza, że po wygenerowaniu pędzla, rogi kontrolki będą przezroczyste! I o to właśnie chodzi – po nałożeniu tej maski na obrazek, przytniemy odpowiednio narożniki. To co było przezroczyste w kontrolce “mask” (narożniki) będzie również niewidzialne na docelowym elemencie (obrazku).
Dzięki wielkie, przydało się. Szukałem po całym necie i tylko to pomogło 🙂