Skill Level Intermediate
- [Instructor] In WPF and other XAML-based UI frameworks the Border element is used to define a border, which is a line that outlines the outside edge of a section of the user interface. Here's an example in this XAML where I've got a Border that contains an Image. The Border is red, the red is defined here. Here's the Border, the red color is defined in a Style Setter up here, so is the BorderThickness and the Centering and the Margin for all of the Borders.
In line 31 I'm defining just one property, the Background color is set to Black. And then inside that is a single element, that's one of the rules of the Border class is it can only have a single child. So in this case it's the Image element. This is a good looking representation, you've got a nice red border around this image. Let's go look at the last column. Here I've also defined a Border, but the major difference here is I've defined a CornerRadius of 42. And when you do that it means that the corners of the border are rounded.
But you can see the problem is in the inner content, which in this case is the image, is not being clipped to match. So we need to fix this, this looks bad. There's a couple of solutions for fixing this, the most obvious one that people first look at is this ClipToBounds, which doesn't work. I could use the Clip property, but to work with that I would have to understand how the geometry classes work and I'd have to create a custom converter class. That would work, but it'd take some effort. With this tip I'll show you a simpler fix using standard WPF elements.
The key to making this work is to use the OpacityMask property. I'll show you an example of a typical use of the OpacityMask, then show you how to use it to clip the border contents. The OpacityMask is used to mask out parts of the UI based on the opacity level. Where the opacity level is low or transparent the mask is applied. Where the opacity level is high or opaque the original UI works. To demonstrate that we'll look at this middle border. So here I've defined the Border, and the Background of the Border is Black, and then the Image sits inside the Border.
So normally you can't see the Black Background of the Border, because the image is overlaid on top of it, but what I'm doing here is I'm applying an OpacityMask on line 38, and then you define an OpacityMask with a Brush, in this case it's a LinearGradientBrush. And I've put two stops in this. One is Transparent and one is opaque. And so you can see where the color is transparent I can see the original image and where the color is opaque I can see the Black Background of the Border.
And I can change this Offset, let's change this to 8, and you can see that that changes how much of it is Transparent and how much of it I can see of the Background Border. So that's the basics of the OpacityMask. Set that back to the original value. So now let's go down to this Border and fix this. So the first fix, the first change I should say to make this is inside the Border I will add a Grid. I'll comment this out for the moment, ctrl + k, ctrl + c, so I have a Grid.
And I'm using a Grid because one of its behaviors is that if you have children in the Grid it expands the children to fit the width and height of the Grid. So within this Grid I'm going to add another Border, so I'll have two Borders, this is the outer Border and this is the inner Border. I'll name this the maskBorder, then I'll set its Background to White, I'll set its CornerRadius to 42, and then the last thing I want to do is I don't want to use the Style that's being applied up here, which is being applied to all Borders.
So I want to set the Style for this inner Border to Null. We're not going to show this Border, what we're going to use is we're going to use this Border as the Brush and apply it to this Image. So the next thing I need to do is put the Image, I'll uncomment this Image, and I'll move this bottom Grid down here, that looks good.
Okay, so let's review what we have so far. We have the outer Border, we have a Grid, we have a inner Border, which is going to serve as the mask, we have the Image, which is also inside the Grid. And I can clean this up, I'll put this slash in there and that removed the end tag. And then the last thing I need to do is set an OpacityMask on this Image. And you saw how we did that here, we used Image.OpacityMask, so let me copy this. And then here I'm going to define a Brush. Remember what I said, it's the Brush that defines the OpacityMask.
And I'm going to use what's called the VisualBrush and VisualBrushes pull the pixels from another part of the UI. So I'm going to pull the pixels for the Brush from this Border. So I'll say Visual= and this is going to use a Binding, and I'll bind it to an element by the name of maskBorder. And you can see I get the IntelliSense inside Visual Studio and once I define the VisualBrush the Binding engine goes out and finds this Border and uses that to define the mask, and here's the key thing, any portion of the Image control that falls outside the boundaries of the inner Border will be masked.
Now when we go back to the visual designer we can see that the OpacityMask is working and this tip is complete.