在WPF中创建对角线模式

时间:2017-03-08 09:31:44

标签: c# wpf

我想在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>

但是用这种图案填充后的形状,我在两条线之间得到了很小的差距。任何人都可以建议一种避免这种小差距的方法吗?

Generate Output

3 个答案:

答案 0 :(得分:8)

DrawingBrushVisualBrush简单得多。

除了中央对角线之外,这条线还绘制了两条额外的线条(当然可以更短)以覆盖画笔瓷砖的右上角和左下角:

<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>

结果是:

enter image description here

这看起来有点稀疏,您可以使用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;
    }
}