#1,059 – Clipping vs. Resizing in a Grid

Grid appears to clip its child elements, in that the elements are constrained to fit within a particular grid cell.

In reality, however, a Grid is often resizing, rather than clipping, the child elements.  If the child element does not specify an explicit size, the Grid will ask the child to be a smaller size, rather than simply clipping it at the grid cell boundary.

Below, the top Button does not have an explicit width, but the bottom Button does.  As we shrink the Grid, the top button will be resized, while the bottom button will be clipped.  The labels indicate the actual button widths.

    <Grid ShowGridLines="True" Background="Bisque"
          Margin="10" ClipToBounds="false">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <Label Content="{Binding ElementName=myButton, Path=ActualWidth}"/>
        <Button Name="myButton" Margin="2"
                Grid.Column="1" Content="Click Here Please"
                HorizontalAlignment="Center"
                VerticalAlignment="Center"/>

        <Label Grid.Row="1" Content="{Binding ElementName=myButton2, Path=ActualWidth}"/>
        <Button Name="myButton2" Margin="2"
                Grid.Row="1" Grid.Column="1" Content="Click Here Please"
                Width="100"
                VerticalAlignment="Center"/>
    </Grid>


1059-001
1059-002

Advertisement

#1,057 – Preventing a Grid from Clipping a Child Element

Grid will normally clip child elements within each grid cell so that the element will not extend beyond the bounds of the cell.  In the example below, the Label in the second column is clipped to the right side of the column.

    <Grid Background="AliceBlue" Margin="25" ShowGridLines="True">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Label Grid.Column="1"
                Content="Each man delights in the work that suits him best." Background="Olive"
                VerticalAlignment="Center"
                Margin="10"/>
    </Grid>

1057-001
If we want to prevent the Grid from clipping the element, we can do this by placing the element in a Canvas, which we then put into the Grid.  Because a Canvas does not clip child elements,  this will allow the element to extend beyond the boundaries of the Grid.

    <Grid Background="AliceBlue" Margin="25" ShowGridLines="True">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Canvas Grid.Column="1">
            <Label Content="Each man delights in the work that suits him best." Background="Olive"
                   VerticalAlignment="Center"
                   Margin="10"/>
        </Canvas>
    </Grid>

1057-002

#1,056 – Grid Clips Child Elements

While a Canvas panel does not clip its child elements, a Grid does clip child elements.  The child elements are clipped even if you set the ClipToBounds property of the Grid to false.

        <Grid Background="AliceBlue" Margin="25" >
            <Label Content="Each man delights in the work that suits him best." Background="Olive"
                   VerticalAlignment="Center" 
                   Margin="10"/>
        </Grid>

1056-001
1056-002

#1,055 – Canvas Does Not Clip Child Elements

By default, the Canvas panel does not clip its child elements at the boundaries of the Canvas.  If the child element does not fit entirely within the Canvas, it will extend beyond the edge of the Canvas.

For example, assume that we put a Label on a Canvas:

    <Canvas Background="AliceBlue" Margin="25">
        <Label Content="Each man delights in the work that suits him best." Background="Olive"
               Margin="10"/>
    </Canvas>

If we place the Canvas in a large enough Window, the Canvas will be large enough to contain the Label.

1055-001

If we now make the window smaller, the Canvas will become smaller and the Label will extend beyond the boundaries of the Canvas.  Note, however that the Label will not extend past the edge of the Window.

1055-002

1055-003

#556 – Clipping to a Border Using an Opacity Mask

When you specify a border radius for a Border element, the content within the Border is not automatically clipped to the new rounded interior.

<Border BorderBrush="Black" BorderThickness="3" Margin="10"
        Width="400" Height="267" CornerRadius="40" >
    <Image Source="Images\Rocks2Small.jpg"/>
</Border>


If you want to clip against the Border, you can specify an opacity mask that is a visual brush bound to the visual of a second Border element that overlays the Image control.  This will cause any portion of the Image control that falls outside the boundaries of the inner Border to use an opacity of 0.0.

<Border BorderBrush="Black" BorderThickness="3" Margin="10" Width="400" Height="267"
	CornerRadius="40" >
    <Grid>
        <Border	Name="myBorder" CornerRadius="40" Background="White" Margin="1"/>
	<Image Source="Images\Rocks2Small.jpg" Margin="1">
	    <Image.OpacityMask>
	        <VisualBrush Visual="{Binding ElementName=myBorder}"/>
	    </Image.OpacityMask>
	</Image>
    </Grid>
</Border>


Thanks to fellow Minnesotan, Chris Cavanagh, for an explanation of how to do this!

#442 – WrapPanel Child Elements Can Be Clipped

By default a WrapPanel will size it’s rows (in Horizontal orientation) or columns (in Vertical orientation) to the size of the tallest/widest element.  This means that no element is ever clipped due to row/column sizing, though they may be clipped if the WrapPanel itself has an explicit size specified.

Child elements can also be clipped if an element ends up larger than the specified ItemWidth and ItemHeight properties.  In the example below, ItemHeight has been set to 50, which is shorter than the Label that has three lines.