Creating Diagonal Pattern in WPF

前端 未结 3 1789
耶瑟儿~
耶瑟儿~ 2020-11-27 22:13

I want to create diagonal hatch pattern in WPF. I am using following XAML code to generate it:

  

        
相关标签:
3条回答
  • 2020-11-27 22:46

    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.

    0 讨论(0)
  • 2020-11-27 22:53

    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>
    
    0 讨论(0)
  • 2020-11-27 22:55

    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;
        }
    }
    
    0 讨论(0)
提交回复
热议问题