Thursday, 7 June 2007

Creating a Hatched / Patterned Brush in WPF

I recently wanted to create a patterned brush in WPF. Of course, WPF is more than capable of doing hatching patterns, but it took me a little while to work out how to do it, especially since the MSDN2 website seems to have lost all example XAML snippets at the moment.
The approach I chose is to use a VisualBrush, although a DrawingBrush would probably work equally well. In the Visual property of the VisualBrush you add your graphics. So for my examples I have one which just has a circle, allowing you to fill an object with dots, and one with two diagonal lines, to create cross-hatching. Then you need to set some additional properties on the VisualBrush:

  • TileMode would be set to Tile as this is a repeating pattern
  • Stretch is set to None
  • The ViewBox rectangle specifies a window onto the Visual allowing you to select just a part of it. Both my fill pattern visuals were 10x10, but I made the ViewBox for the dot fill 12x12 which effectively added some spacing between the dots.
  • The ViewPort rectangle gives more flexibility by specifying the position and dimensions of the first "tile". Normally you would simply set this to the same as the ViewBox, but you could use it to scale the tiled image in X or Y dimensions, or effectively slide the tiles across.

Here's some example XAML:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:sys="clr-namespace:System;assembly=mscorlib" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
  <VisualBrush 
    x:Key="DotFillBrush" 
    TileMode="Tile" 
    Viewport="0,0,10,10" 
    ViewportUnits="Absolute" 
    Viewbox="0,0,12,12"
    ViewboxUnits="Absolute">
    <VisualBrush.Visual>
      <Ellipse 
        Fill="#00C0FF" 
        Width="10" Height="10" />
      </VisualBrush.Visual>
    </VisualBrush>      
    <VisualBrush 
      x:Key="HatchBrush" 
      TileMode="Tile" Viewport="0,0,10,10" 
      ViewportUnits="Absolute" Viewbox="0,0,10,10"    
      ViewboxUnits="Absolute">
      <VisualBrush.Visual>
        <Canvas>
           <Rectangle Fill="Azure" Width="10" Height="10" />
           <Path Stroke="Purple" Data="M 0 0 l 10 10" />
           <Path Stroke="Purple" Data="M 0 10 l 10 -10" />
        </Canvas>
      </VisualBrush.Visual>
   </VisualBrush>      
</Page.Resources>

<Canvas>
<Rectangle Canvas.Top="20" Canvas.Left="20" 
  Width="80" Height="40" 
  Fill="{StaticResource DotFillBrush}"/>
<Rectangle Canvas.Top="20" Canvas.Left="120" 
  Width="80" Height="40" 
  Fill="{StaticResource HatchBrush}"/>
<TextBlock Canvas.Top="80" Canvas.Left="20" 
  Text="Hello" FontSize="80" 
  Foreground="{StaticResource DotFillBrush}"/>
<TextBlock Canvas.Top="80" Canvas.Left="220" 
  Text="World" FontSize="80" 
  Foreground="{StaticResource HatchBrush}"/>
</Canvas>
</Page>

And here's what it looks like:

WPF Patterned & Hatched Brushes

Post a Comment