TileBrush Overview

TileBrush objects provide you with a great deal of control over how an area is painted with an image, Drawing, or Visual. This topic describes how to use TileBrush features to gain more control over how an ImageBrush, DrawingBrush, or VisualBrush paints an area.

Prerequisites

To understand this topic, it's helpful to understand how to use the basic features of the ImageBrush, DrawingBrush, or VisualBrush class. For an introduction to these types, see the Painting with Images, Drawings, and Visuals.

Painting an Area with Tiles

ImageBrush, DrawingBrush, are VisualBrush are types of TileBrush objects. Tile brushes provide you with a great deal of control over how an area is painted with an image, drawing, or visual. For example, instead of just painting an area with a single stretched image, you can paint an area with a series of image tiles that create a pattern.

Painting an area with a tile brush involves three components: content, the base tile, and the output area.

TileBrush components
Components of a TileBrush with a single tile

Components of a tiled TileBrush
Components of a TileBrush with a TileMode of Tile

The output area is the area being painted, such as the Fill of an Ellipse or the Background of a Button. The next sections describe the other two components of a TileBrush.

Brush Content

There are three different types of TileBrush and each paints with a different type of content.

You can specify the position and dimensions of TileBrush content by using the Viewbox property, although it is common to leave the Viewbox set to its default value. By default, the Viewbox is configured to completely contain the brush's contents. For more information about configuring the Viewbox, see the Viewbox property page.

The Base Tile

A TileBrush projects its content onto a base tile. The Stretch property controls how TileBrush content is stretched to fill the base tile. The Stretch property accepts the following values, defined by the Stretch enumeration:

  • None: The brush's content is not stretched to fill the tile.

  • Fill: The brush's content is scaled to fit the tile. Because the content's height and width are scaled independently, the original aspect ratio of the content might not be preserved. That is, the brush's content might be warped in order to completely fill the output tile.

  • Uniform: The brush's content is scaled so that it fits completely within the tile. The content's aspect ratio is preserved.

  • UniformToFill: The brush's content is scaled so that it completely fills the output area while preserving the content's original aspect ratio.

The following image illustrates the different Stretch settings.

Different TileBrush Stretch settings

In the following example, the content of an ImageBrush is set so that it does not stretch to fill the output area.

<Rectangle
  Width="125" Height="175"
  Stroke="Black"
  StrokeThickness="1"
  Margin="0,0,5,0">
  <Rectangle.Fill>
    <ImageBrush 
      Stretch="None"
      ImageSource="sampleImages\testImage.gif"/>
  </Rectangle.Fill>
</Rectangle>
// Create a rectangle.
Rectangle myRectangle = new Rectangle();
myRectangle.Width = 125;
myRectangle.Height = 175;
myRectangle.Stroke = Brushes.Black;
myRectangle.StrokeThickness = 1;
myRectangle.Margin = new Thickness(0,5,0,0);

// Load the image.
BitmapImage theImage =
    new BitmapImage(
        new Uri("sampleImages\\testImage.gif", UriKind.Relative));
ImageBrush myImageBrush = new ImageBrush(theImage);

// Configure the brush so that it
// doesn't stretch its image to fill
// the rectangle.
myImageBrush.Stretch = Stretch.None;

// Use the ImageBrush to paint the rectangle's background.
myRectangle.Fill = myImageBrush;
' Create a rectangle.
Dim myRectangle As New Rectangle()
With myRectangle
    .Width = 125
    .Height = 175
    .Stroke = Brushes.Black
    .StrokeThickness = 1
    .Margin = New Thickness(0, 5, 0, 0)
End With

' Load the image.
Dim theImage As New BitmapImage(New Uri("sampleImages\testImage.gif", UriKind.Relative))
Dim myImageBrush As New ImageBrush(theImage)

' Configure the brush so that it
' doesn't stretch its image to fill
' the rectangle.
myImageBrush.Stretch = Stretch.None

' Use the ImageBrush to paint the rectangle's background.
myRectangle.Fill = myImageBrush

By default, a TileBrush generates a single tile (the base tile) and stretches that tile to completely fill the output area. You can change the size and position of the base tile by setting the Viewport and ViewportUnits properties.

Base Tile Size

The Viewport property determines the size and position of the base tile, and the ViewportUnits property determines whether the Viewport is specified using absolute or relative coordinates. If the coordinates are relative, they are relative to the size of the output area. The point (0,0) represents the top left corner of the output area, and (1,1) represents the bottom right corner of the output area. To specify that the Viewport property uses absolute coordinates, set the ViewportUnits property to Absolute.

The following illustration shows the difference in output between a TileBrush with relative versus absolute ViewportUnits. Notice that the illustrations each show a tiled pattern; the next section describes how to specify tile pattern.

Absolute and Relative Viewport Units

In the following example, an image is used to create a tile that has a width and height of 50%. The base tile is located at (0,0) of the output area.

<Rectangle
 Width="50" Height="100">
  <Rectangle.Fill>

    <!-- Paints an area with 4 tiles. -->
    <ImageBrush ImageSource="sampleImages\cherries_larger.jpg"
      Viewport="0,0,0.5,0.5"
      ViewportUnits="RelativeToBoundingBox" 
      TileMode="Tile" />
  </Rectangle.Fill>
</Rectangle>
// Create a rectangle.
Rectangle myRectangle = new Rectangle();
myRectangle.Width = 50;
myRectangle.Height = 100;

// Load the image.
BitmapImage theImage =
    new BitmapImage(
        new Uri("sampleImages\\cherries_larger.jpg", UriKind.Relative));
ImageBrush myImageBrush = new ImageBrush(theImage);

// Create tiles that are 1/4 the size of
// the output area.
myImageBrush.Viewport = new Rect(0,0,0.25,0.25);
myImageBrush.ViewportUnits = BrushMappingMode.RelativeToBoundingBox;

// Set the tile mode to Tile.
myImageBrush.TileMode = TileMode.Tile;

// Use the ImageBrush to paint the rectangle's background.
myRectangle.Fill = myImageBrush;
' Create a rectangle.
Dim myRectangle As New Rectangle()
myRectangle.Width = 50
myRectangle.Height = 100

' Load the image.
Dim theImage As New BitmapImage(New Uri("sampleImages\cherries_larger.jpg", UriKind.Relative))
Dim myImageBrush As New ImageBrush(theImage)

' Create tiles that are 1/4 the size of 
' the output area.
myImageBrush.Viewport = New Rect(0, 0, 0.25, 0.25)
myImageBrush.ViewportUnits = BrushMappingMode.RelativeToBoundingBox

' Set the tile mode to Tile.
myImageBrush.TileMode = TileMode.Tile

' Use the ImageBrush to paint the rectangle's background.
myRectangle.Fill = myImageBrush

The next example sets the tiles of an ImageBrush to 25 by 25 device independent pixels. Because the ViewportUnits are absolute, the ImageBrush tiles are always 25 by 25 pixels, regardless of the size of the area being painted.

<Rectangle
 Width="50" Height="100">
  <Rectangle.Fill>

    <!-- Paints an area with 25 x 25 tiles. -->
    <ImageBrush ImageSource="sampleImages\cherries_larger.jpg"
      Viewport="0,0,25,25"
      ViewportUnits="Absolute" 
      TileMode="Tile" />
  </Rectangle.Fill>
</Rectangle>
// Create a rectangle.
Rectangle myRectangle = new Rectangle();
myRectangle.Width = 50;
myRectangle.Height = 100;

// Load the image.
BitmapImage theImage =
    new BitmapImage(
        new Uri("sampleImages\\cherries_larger.jpg", UriKind.Relative));
ImageBrush myImageBrush = new ImageBrush(theImage);

// Create tiles that are 25 x 25, regardless of the size
// of the output area.
myImageBrush.Viewport = new Rect(0, 0, 25, 25);
myImageBrush.ViewportUnits = BrushMappingMode.Absolute;

// Set the tile mode to Tile.
myImageBrush.TileMode = TileMode.Tile;

// Use the ImageBrush to paint the rectangle's background.
myRectangle.Fill = myImageBrush;
' Create a rectangle.
Dim myRectangle As New Rectangle()
myRectangle.Width = 50
myRectangle.Height = 100

' Load the image.       
Dim theImage As New BitmapImage(New Uri("sampleImages\cherries_larger.jpg", UriKind.Relative))
Dim myImageBrush As New ImageBrush(theImage)

' Create tiles that are 25 x 25, regardless of the size
' of the output area.
myImageBrush.Viewport = New Rect(0, 0, 25, 25)
myImageBrush.ViewportUnits = BrushMappingMode.Absolute

' Set the tile mode to Tile.
myImageBrush.TileMode = TileMode.Tile

' Use the ImageBrush to paint the rectangle's background.
myRectangle.Fill = myImageBrush

Tiling Behavior

A TileBrush produces a tiled pattern when its base tile does not completely fill the output area and a tiling mode other then None is specified. When a tile brush's tile does not completely fill the output area, its TileMode property specifies whether the base tile should be duplicated to fill the output area and, if so, how the base tile should be duplicated. The TileMode property accepts the following values, defined by the TileMode enumeration:

  • None: Only the base tile is drawn.

  • Tile: The base tile is drawn and the remaining area is filled by repeating the base tile such that the right edge of one tile is adjacent to the left edge of the next, and similarly for bottom and top.

  • FlipX: The same as Tile, but alternate columns of tiles are flipped horizontally.

  • FlipY: The same as Tile, but alternate rows of tiles are flipped vertically.

  • FlipXY: A combination of FlipX and FlipY.

The following image illustrates the different tiling modes.

Different TileBrush TileMode settings

In the following example, an image is used to paint a rectangle that is 100 pixels wide and 100 pixels tall. By setting the brush's Viewport has been set to 0,0,0.25,0.25, the brush's base tile is made to be 1/4 of the output area. The brush's TileMode is set to FlipXY. so that it fills the rectangle with rows of tiles.

<Rectangle
 Width="100" Height="100" >
  <Rectangle.Fill>
    <ImageBrush ImageSource="sampleImages\triangle.jpg"
      Viewport="0,0,0.25,0.25" 
      TileMode="FlipXY"
      />
  </Rectangle.Fill>    
</Rectangle>
// Create a rectangle.
Rectangle myRectangle = new Rectangle();
myRectangle.Width = 100;
myRectangle.Height = 100;

// Load the image.
BitmapImage theImage =
    new BitmapImage(
        new Uri("sampleImages\\triangle.jpg", UriKind.Relative));
ImageBrush myImageBrush = new ImageBrush(theImage);

// Create tiles that are 1/4 the size of
// the output area.
myImageBrush.Viewport = new Rect(0,0,0.25,0.25);

// Set the tile mode to FlipXY.
myImageBrush.TileMode = TileMode.FlipXY;

// Use the ImageBrush to paint the rectangle's background.
myRectangle.Fill = myImageBrush;
' Create a rectangle.
Dim myRectangle As New Rectangle()
myRectangle.Width = 100
myRectangle.Height = 100

' Load the image.
Dim theImage As New BitmapImage(New Uri("sampleImages\triangle.jpg", UriKind.Relative))
Dim myImageBrush As New ImageBrush(theImage)

' Create tiles that are 1/4 the size of 
' the output area.
myImageBrush.Viewport = New Rect(0, 0, 0.25, 0.25)

' Set the tile mode to FlipXY.
myImageBrush.TileMode = TileMode.FlipXY

' Use the ImageBrush to paint the rectangle's background.
myRectangle.Fill = myImageBrush

See also