I want to create diagonal hatch pattern in WPF. I am using following XAML code to generate it:
You could use VisualBrush.Transform
:
<VisualBrush x:Key="HatchBrushnew"
TileMode="Tile"
Viewport="0,0,30,30"
ViewportUnits="Absolute"
Viewbox="0,0,30,30"
ViewboxUnits="Absolute">
<VisualBrush.Transform>
<RotateTransform Angle="135" CenterX=".5" CenterY=".5" />
</VisualBrush.Transform>
<VisualBrush.Visual>
<Canvas>
<Path Stroke="Gray" StrokeThickness="0.1cm" >
<Path.Data>
<LineGeometry StartPoint="15,0" EndPoint="15,30" />
</Path.Data>
</Path>
</Canvas>
</VisualBrush.Visual>
</VisualBrush>
And the result is:
This appears a bit more sparse, you could play around with the values of VisualBrush.Viewport
to fix that. Since we are rotating 135 degrees, the spacing is in fact sqrt(2) times larger than the original one, you could use it as a hint.
A DrawingBrush
would be much simpler than a VisualBrush
.
In addition to the central diagonal line, this one draws two additional lines (which may of course be shorter) to cover the top right and bottom left corners of the Brush tile:
<DrawingBrush x:Key="HatchBrush" TileMode="Tile"
Viewport="0,0,30,30" ViewportUnits="Absolute"
Viewbox="0,0,30,30" ViewboxUnits="Absolute">
<DrawingBrush.Drawing>
<GeometryDrawing>
<GeometryDrawing.Pen>
<Pen Brush="Black" Thickness="5"/>
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<Geometry>M0,0 L30,30 M15,-15 L45,15 M-15,15 L15,45</Geometry>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
As shown in the answer given by Balázs, you may also set the Brush's Transform
property, and use e.g. a single vertical LineGeometry
:
<DrawingBrush x:Key="HatchBrush" TileMode="Tile"
Viewport="0,0,30,30" ViewportUnits="Absolute"
Viewbox="0,0,30,30" ViewboxUnits="Absolute">
<DrawingBrush.Transform>
<RotateTransform Angle="45"/>
</DrawingBrush.Transform>
<DrawingBrush.Drawing>
<GeometryDrawing>
<GeometryDrawing.Pen>
<Pen Brush="Black" Thickness="5"/>
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<LineGeometry StartPoint="0,15" EndPoint="30,15"/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
Here the coded variant to @Balázs solution (in VB)
Public ReadOnly Property fill As Brush
Get
Dim FillColor As Color
Dim HatchThickness As Double
Dim HatchAngle As Double
FillColor = Colors.Black
HatchThickness = 3
HatchAngle = 45
'
' https://stackoverflow.com/questions/42667566/creating-diagonal-pattern-in-wpf
' and
' https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/wpf-brushes-overview#paint-with-a-drawing
'
Dim myBrush As New DrawingBrush()
Dim myGeometryGroup As New GeometryGroup()
'
' add a horizontal line to the geometry group
'
myGeometryGroup.Children.Add(New LineGeometry(New Windows.Point(0, 0), New Windows.Point(10, 0)))
'
' draw geometry with transparent brush and pen as defined
'
Dim p As New Windows.Media.Pen
p.Brush = New SolidColorBrush(FillColor)
p.Thickness = HatchThickness
p.StartLineCap = PenLineCap.Square
p.EndLineCap = PenLineCap.Square
Dim myDrawing As New GeometryDrawing(Nothing, p, myGeometryGroup)
'
' apply the drawing to the brush
'
myBrush.Drawing = myDrawing
'
' in case, there is more than one line use a Drawing Group
'
'Dim myDrawingGroup As New DrawingGroup()
'myDrawingGroup.Children.Add(checkers)
'myBrush.Drawing = myDrawingGroup
' set viewbox and viewport
myBrush.Viewbox = New Windows.Rect(0, 0, 10, 10)
myBrush.ViewboxUnits = BrushMappingMode.Absolute
myBrush.Viewport = New Windows.Rect(0, 0, 10, 10)
myBrush.ViewportUnits = BrushMappingMode.Absolute
myBrush.TileMode = TileMode.Tile
myBrush.Stretch = Stretch.UniformToFill
' rotate
myBrush.Transform = New RotateTransform(HatchAngle)
Return myBrush
End Get
End Property
and in C#
public Brush fill
{
get
{
Color FillColor;
double HatchThickness;
double HatchAngle;
FillColor = Colors.Black;
HatchThickness = 3;
HatchAngle = 45;
//
// https://stackoverflow.com/questions/42667566/creating-diagonal-pattern-in-wpf
// and
// https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/wpf-brushes-overview#paint-with-a-drawing
//
DrawingBrush myBrush = new DrawingBrush();
GeometryGroup myGeometryGroup = new GeometryGroup();
//
// add a horizontal line to the geometry group
//
myGeometryGroup.Children.Add(new LineGeometry(new Windows.Point(0, 0), new Windows.Point(10, 0)));
//
// draw geometry with transparent brush and pen as defined
//
Windows.Media.Pen p = new Windows.Media.Pen();
p.Brush = new SolidColorBrush(FillColor);
p.Thickness = HatchThickness;
p.StartLineCap = PenLineCap.Square;
p.EndLineCap = PenLineCap.Square;
GeometryDrawing myDrawing = new GeometryDrawing(null/* TODO Change to default(_) if this is not a reference type */, p, myGeometryGroup);
//
// apply the drawing to the brush
//
myBrush.Drawing = myDrawing;
//
// in case, there is more than one line use a Drawing Group
//
// Dim myDrawingGroup As New DrawingGroup()
// myDrawingGroup.Children.Add(checkers)
// myBrush.Drawing = myDrawingGroup
// set viewbox and viewport
myBrush.Viewbox = new Windows.Rect(0, 0, 10, 10);
myBrush.ViewboxUnits = BrushMappingMode.Absolute;
myBrush.Viewport = new Windows.Rect(0, 0, 10, 10);
myBrush.ViewportUnits = BrushMappingMode.Absolute;
myBrush.TileMode = TileMode.Tile;
myBrush.Stretch = Stretch.UniformToFill;
// rotate
myBrush.Transform = new RotateTransform(HatchAngle);
return myBrush;
}
}