TileBrush 概述

使用 TileBrush 对象,可以非常自如地控制如何使用图像、DrawingVisual 来绘制区域。 本主题介绍如何使用 TileBrush 功能来更好地控制 ImageBrushDrawingBrushVisualBrush 绘制区域的方式。

先决条件

若要了解本主题,了解如何使用 ImageBrushDrawingBrushVisualBrush 类的基本功能会很有帮助。 有关这些类型的简介,请参阅使用图像、绘图和视觉对象进行绘制

使用图块绘制区域

ImageBrushDrawingBrushVisualBrushTileBrush 对象的类型。 使用平铺画笔,可以非常自如地控制如何使用图像、绘图或视觉对象来绘制区域。 例如,在绘制一个区域时,可以使用一系列的图像图块创建图案,而不是仅使用拉伸的图像。

使用平铺画笔绘制区域涉及三个组成部分:内容、基本图块和输出区域。

TileBrush components
具有单个图块的 TileBrush 的组成部分

Components of a tiled TileBrush
已指定图块的 TileMode 的 TileBrush 的组成部分

输出区域为正在绘制的区域,例如 EllipseFillButtonBackground。 以下各部分将介绍 TileBrush 的另外两个组件。

画笔内容

TileBrush 有三种不同类型,其中每一种都使用不同类型的内容进行绘制。

可以使用 Viewbox 属性指定 TileBrush 内容的位置和维度,但通常将 Viewbox 保留为其默认值。 默认情况下,Viewbox 配置为完全包含画笔的内容。 若要详细了解如何配置 Viewbox,请参阅 Viewbox 属性页。

基本图块

TileBrush 将其内容投影到基本图块上。 Stretch 属性控制如何拉伸 TileBrush 内容以填充基本图块。 Stretch 属性接受由 Stretch 枚举定义的以下值:

  • None:不通过拉伸画笔的内容来填充图块。

  • Fill:缩放画笔的内容,使其位于图块内。 由于内容的高度和宽度独立进行缩放,因此内容的原始纵横比可能不会保留。 也就是说,为了完全填充输出图块,画笔的内容可能会弯曲。

  • Uniform:缩放画笔的内容,使其完全位于图块内。 内容的纵横比会保留。

  • UniformToFill:缩放画笔的内容,使其完全填充输出区域,同时保持内容的原始纵横比。

下图阐释了不同的 Stretch 设置。

Different TileBrush Stretch settings

在以下示例中,设置 ImageBrush 的内容,使其不通过拉伸来填充输出区域。

<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

默认情况下,TileBrush 生成单个图块(基本图块)并拉伸该图块以完全填充输出区域。 可以通过设置 ViewportViewportUnits 属性来更改基本图块的大小和位置。

基本图块大小

Viewport 属性确定基本图块的大小和位置,而 ViewportUnits 属性确定是使用绝对坐标还是相对坐标来指定 Viewport。 如果坐标是相对坐标,则它们相对于输出区域的大小。 点 (0,0) 表示输出区域的左上角,(1,1) 表示输出区域的右下角。 若要指定 Viewport 属性使用绝对坐标,请将 ViewportUnits 属性设置为 Absolute

下图显示了具有相对和绝对 ViewportUnitsTileBrush 之间的输出差异。 请注意每个图都显示了一种图块图案;下一节介绍如何指定图块图案。

Absolute and Relative Viewport Units

在下面的示例中,使用一幅图像来创建一个宽度和高度均为 50% 的图块。 基本图块位于输出区域的 (0,0) 处。

<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

下一个示例将 ImageBrush 的图块设置为 25 x 25 与设备无关的像素。 由于 ViewportUnits 是绝对的,因此 ImageBrush 图片始终为 25 x 25 像素,而与所绘制区域的大小无关。

<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

平铺行为

TileBrush 的基本图块未完全填充输出区域并且指定了除 None 以外的平铺模式时,它将生成一个平铺图案。 当平铺画笔的图块未完全填充输出区域时,其 TileMode 属性指定是否应复制基本图块来填充输出区域,在需要复制的情况下应指定复制基本图块的方式。 TileMode 属性接受由 TileMode 枚举定义的以下值:

  • None:仅绘制基本图块。

  • Tile:绘制基本图块,并通过重复基本图块来填充剩余的区域,使一个图块的右边缘靠近下一个图块的左边缘,下边缘和上边缘也是如此。

  • FlipX:与 Tile 相同,只不过磁贴的交替列被水平翻转。

  • FlipY:与 Tile 相同,只不过磁贴的交替行被垂直翻转。

  • FlipXYFlipXFlipY 的组合。

下图阐释了不同的平铺模式。

Different TileBrush TileMode settings

在下面的示例中,使用一个图像来绘制宽度为 100 像素并且高度为 100 像素的矩形。 通过将画笔的 Viewport 设置为 0,0,0.25,0.25,使画笔的基本图块占输出区域的 1/4。 画笔的 TileMode 设置为 FlipXY。 这样它便可以用图块行来填充矩形。

<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

另请参阅