2011-06-22 38 views
12

Necesito construir una línea de cuadrícula de dibujo función en el lienzo en WPF:Cómo dibujar la cuadrícula en 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? 
} 

¿cómo iba a ir sobre esto?

Respuesta

29

No tiene que "dibujar" nada con WPF. Si desea dibujar líneas, use las geometrías apropiadas para dibujarlas.

En su caso, podría ser realmente simple. Solo está dibujando una cuadrícula, por lo que podría crear un DrawingBrush para dibujar un solo cuadrado y colocarlo en mosaico para completar el resto. Para dibujar su baldosa, podría pensar que dibuja X. Así que para tener una baldosa 20x10 (que corresponde a stepX y stepY):

(ps, la pendiente slop es redundante puesto que ya tiene el tamaño horizontal y vertical de paso)

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

que se encarga de dibujo las líneas. Ahora, para poder dibujarlos desplazados en su cuadrícula desde los bordes, debe tener otro pincel donde dibuje un rectángulo con las dimensiones deseadas, rellenas con sus teselas. Así que para tener una posición de partida de (30, 45) (correspondiente a startX y startY) con el width y height, 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> 

Entonces finalmente a usarlo, simplemente establecerla como fondo de la rejilla (u otro panel) :

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

Así es como termina pareciéndose a:

final look


Si desea generar el cepillo de forma dinámica, aquí es una función equivalente basado en el XAML anterior:

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

Muchas gracias !!! Tu código es perfecto! – Renaud

+0

Este código es absolutamente increíble, y gracias por compartirlo, pero en cuanto al código equivalente de C# para crearlo dinámicamente, solo tengo algunas preguntas: parece que no puedo crear un pincel usando esto, debido a problemas de herencia de clase abstracta. Solo curiosidad por cómo crear uno a través de este método? – WearyWanderer

Cuestiones relacionadas