开发者

Canvas with transforms - what's the best way to draw a grid

I have a WPF canvas that I can scale, scroll and whatever. Now I want to draw (tiling) gridlines on it - preferably depending on the scale, which means that when you zoom out the old gridlines fade away and new (bigger scale, but due to zooming seemingly the same) gridlines fade in.

I've heard 开发者_如何学Pythonsome people yelling "Tilebrush!", but I can't google any example of it.

Can anybody point me in the right direction - not just to the MSDN page of the tilebrush, but on how to efficiently draw gridlines on my zoomable canvas ? :)


The easiest solution is to use a VisualBrush to draw your gridlines:

<Canvas>
  <Canvas.Background>
    <VisualBrush TileMode="Tile" Stretch="Fill" Viewport="0 0 50 50" ViewportUnits="Absolute" ViewboxUnits="Absolute" >
      <VisualBrush.Visual>
        <Grid>
          <Rectangle Width="1" Height="0.03" Fill="Gray" HorizontalAlignment="Left" VerticalAlignment="Top" />
          <Rectangle Height="1" Width="0.03" Fill="Gray" HorizontalAlignment="Left" VerticalAlignment="Top" />
        </Grid>
      </VisualBrush.Visual>
    </VisualBrush>
  </Canvas.Background>
</Canvas>

You can change the gridlines by adjusting the Viewport coordinates and the gridline width by adjusting the rectangle Height and Width (currrently 0.03).

A more efficient solution is available using a DrawingBrush, but working with drawings is not as simple. This draws gridlines using a DrawingBrush:

<Canvas>
  <Canvas.Background>
    <DrawingBrush TileMode="Tile" Stretch="Fill" Viewport="0 0 50 50" ViewportUnits="Absolute" ViewboxUnits="Absolute" >
      <DrawingBrush.Drawing>
        <GeometryDrawing Geometry="M0,0 L0,1 0.03,1 0.03,0.03 1,0.03 1,0 Z" Brush="Gray" />
      </DrawingBrush.Drawing>
    </DrawingBrush>
  </Canvas.Background>
</Canvas>

To change the gridlines as you zoom out, just recompute them whenever the zoom changes. You can determine just how zoomed-in a given visual is with this code:

var zoom = visual
             .TransformToAncestor(Window.FromVisual(visual))
             .Transform(new Point(1,1));

if(zoom.X>10 || zoom.Y>10)
  // Use finer gridlines
else
  // Use coarser gridlines

If you really want to "fade in" the gridlines, you can use two Canvasas under your main Canvas, and set the opacity on the finer gridlines as a function of the exact zoom in use.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜