2011-06-22 255 views
12

我需要建立在WPF在画布上绘制功能网格线:如何在WPF Canvas上绘制网格线?

example gridline

void DrawGridLine(double startX, double startY, double stepX, double stepY, 
        double slop, double width, double height) 
{ 
    // How to implement draw gridline here? 
} 

我怎么会去吗?

回答

29

你并不需要用WPF“画”任何东西。如果要绘制线条,请使用适当的几何图形绘制线条。

在你的情况下,它可能很简单。你只是绘制一个网格,所以你可以创建一个DrawingBrush来绘制一个单一的网格正方形,并将其平铺以填充其余部分。要绘制您的图块,您可以将其视为绘制X的。所以有一个20x10瓦(相当于stepXstepY):

(PS,斜率slop是多余的,因为你已经拥有水平和垂直步长)

<DrawingBrush x:Key="GridTile" Stretch="None" TileMode="Tile" 
       Viewport="0,0 20,10" ViewportUnits="Absolute"> 
        <!-- ^^^^^^^^^^^ set the size of the tile--> 
    <DrawingBrush.Drawing> 
     <GeometryDrawing> 
      <GeometryDrawing.Geometry> 
       <!-- draw a single X --> 
       <GeometryGroup> 
        <!-- top-left to bottom-right --> 
        <LineGeometry StartPoint="0,0" EndPoint="20,10" /> 

        <!-- bottom-left to top-right --> 
        <LineGeometry StartPoint="0,10" EndPoint="20,0" /> 
       </GeometryGroup> 
      </GeometryDrawing.Geometry> 
      <GeometryDrawing.Pen> 
       <!-- set color and thickness of lines --> 
       <Pen Thickness="1" Brush="Black" /> 
      </GeometryDrawing.Pen> 
     </GeometryDrawing> 
    </DrawingBrush.Drawing> 
</DrawingBrush> 

这需要绘图的护理线。现在为了能够从边缘绘制它们在网格中的偏移量,您需要使用另一个画笔绘制具有所需尺寸的矩形,并用瓦片填充。所以有(30, 45)(对应于startXstartY)与widthheight起始位置,130x120

<DrawingBrush x:Key="OffsetGrid" Stretch="None" AlignmentX="Left" AlignmentY="Top"> 
    <DrawingBrush.Transform> 
     <!-- set the left and top offsets --> 
     <TranslateTransform X="30" Y="45" /> 
    </DrawingBrush.Transform> 
    <DrawingBrush.Drawing> 
     <GeometryDrawing Brush="{StaticResource GridTile}" > 
      <GeometryDrawing.Geometry> 
       <!-- set the width and height filled with the tile from the origin --> 
       <RectangleGeometry Rect="0,0 130,120" /> 
      </GeometryDrawing.Geometry> 
     </GeometryDrawing> 
    </DrawingBrush.Drawing> 
</DrawingBrush> 

后来终于用它,只是把它设置为网格的背景(或其他面板) :

<Grid Background="{StaticResource OffsetGrid}"> 
    <!-- ... --> 
</Grid> 

下面是它的最终看起来像:

final look


如果要动态地生成刷,这里的基于上述XAML等效功能:

static Brush CreateGridBrush(Rect bounds, Size tileSize) 
{ 
    var gridColor = Brushes.Black; 
    var gridThickness = 1.0; 
    var tileRect = new Rect(tileSize); 

    var gridTile = new DrawingBrush 
    { 
     Stretch = Stretch.None, 
     TileMode = TileMode.Tile, 
     Viewport = tileRect, 
     ViewportUnits = BrushMappingMode.Absolute, 
     Drawing = new GeometryDrawing 
     { 
      Pen = new Pen(gridColor, gridThickness), 
      Geometry = new GeometryGroup 
      { 
       Children = new GeometryCollection 
       { 
        new LineGeometry(tileRect.TopLeft, tileRect.BottomRight), 
        new LineGeometry(tileRect.BottomLeft, tileRect.TopRight) 
       } 
      } 
     } 
    }; 

    var offsetGrid = new DrawingBrush 
    { 
     Stretch = Stretch.None, 
     AlignmentX = AlignmentX.Left, 
     AlignmentY = AlignmentY.Top, 
     Transform = new TranslateTransform(bounds.Left, bounds.Top), 
     Drawing = new GeometryDrawing 
     { 
      Geometry = new RectangleGeometry(new Rect(bounds.Size)), 
      Brush = gridTile 
     } 
    }; 

    return offsetGrid; 
} 
+4

非常感谢!你的代码是完美的! – Renaud

+0

这段代码绝对是真棒,感谢分享,但对于动态创建它的c#等价代码,我只是有一些问题 - 由于抽象类继承问题,我似乎无法使用此创建画笔。只是好奇你将如何通过这种方法创建一个? – WearyWanderer