我想在WPF中创建对角线阴影图案。我正在使用以下XAML代码来生成它:
<VisualBrush
x:Key="HatchBrushnew"
TileMode="Tile" Viewport="0,0,30,30"
ViewportUnits="Absolute" Viewbox="0,0,30,30"
ViewboxUnits="Absolute">
<VisualBrush.Visual>
<Canvas>
<Path Stroke="Gray" StrokeThickness="0.1cm" >
<Path.Data>
<LineGeometry StartPoint="0,0" EndPoint="30,30" />
</Path.Data>
</Path>
</Canvas>
</VisualBrush.Visual>
</VisualBrush>
但是用这种图案填充后的形状,我在两条线之间得到了很小的差距。任何人都可以建议一种避免这种小差距的方法吗?
答案 0 :(得分:8)
DrawingBrush
比VisualBrush
简单得多。
除了中央对角线之外,这条线还绘制了两条额外的线条(当然可以更短)以覆盖画笔瓷砖的右上角和左下角:
<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>
如Balázs给出的答案所示,您也可以设置Brush的Transform
属性,并使用例如单一垂直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>
答案 1 :(得分:2)
您可以使用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>
结果是:
这看起来有点稀疏,您可以使用VisualBrush.Viewport
的值来解决这个问题。由于我们旋转135度,因此间距实际上是原始间距的sqrt(2)倍,您可以将其用作提示。
答案 2 :(得分:0)
这里是@Balázs解决方案的编码变体(在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
和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;
}
}