在WPF中绘制一个淡入淡出的网格

时间:2013-08-23 08:24:38

标签: c# wpf canvas

我正在尝试绘制一个像网格的图纸作为画布的背景。这个网格不同于我发现的如何做到这一点的大多数解释,因为画布可以缩放以实现缩放。我想要做的是有一系列网格线,即每10 ^ n单位。然后,由于变焦,网格线在它们变得靠近时会逐渐淡出。换句话说,如果n很大,那么与该网格相关联的线应该比较小的n更重/更重。

这在WinForms中很容易实现,我通过重写OnPaint并将线的颜色定义为到下一个网格线的距离的函数来实现它。相距较远的线路比较靠近的线路重量更重。

我还没想出如何在WPF中执行此操作。我可以通过根据网格线的间距创建具有StrokeThickness的线来获得此行为,但这仅适用于小范围的StrokeThickness和缩放值。如果可以将一条线定义为具有非常重的重量,但仍然是一个小的StrokeThickness,它将起作用。

即使通过使用OnRender实现自定义控件来实现这一点也很困难,因为我没有找到一种可靠的方法来获取控件的比例(ScaleTransform是其中一个父控件的一部分,而不是直接父控件)

对于如何实现这一目标的任何想法都将不胜感激!

1 个答案:

答案 0 :(得分:2)

我通过不将网格添加到画布但通过将画布堆叠在包含网格的另一个控件的顶部来解决这个问题:

<Grid>
    <Canvas x:Name="GridLayer"/>
    <Canvas x:Name="DrawingLayer" />
</Grid>

当缩放事件发生时,我只需重绘GridLayer。

这允许我只绘制所需的线条,准确地绘制它们我想要的线条,在我的情况下非常重要,因为我可能有很多网格线,我不需要再划线了/比需要的高。这样我节省了大量的CPU时间。

需要注意的另一件事是我实现了自己的缩放代码。我没有使用RenderTransform或ViewBox,因为我希望线条保持相同的宽度。我所做的只是跟踪左上角的坐标以支持平移和缩放级别。只要其中一个更改我重绘画布。我写了两个函数:一个将Canvas上的坐标转换为图形坐标,另一个反转。第一种方法允许我将光标坐标转换为图形坐标,第二种方法将图形的坐标转换为可用于在画布上绘制的点。

未经测试的代码并对轴的方向做了很多假设:

Point Graph2Canvas(Point graphPoint)
{
    var canvasPoint = new Point(graphPoint);
    canvasPoint.X *= zoomLevel;
    canvasPoint.Y *= zoomLevel;
    canvasPoint.X -= topLeft.X;
    canvasPoint.Y -= topLeft.Y;
    return canvasPoint;
}

这可以被优化,事实是我创造了更多的功能,为点集合做同样的事情。

额外:

我最终得到了一个更复杂的设置,看起来有点像这样:

<Grid>
    <Canvas x:Name="BackgroundLayer"/>
    <Canvas x:Name="GridLayer"/>
    <Canvas x:Name="AxisLayer"/>
    <Canvas x:Name="DrawingLayer" />
    <Canvas x:Name="SelectionBoxLayer"/>
    <Canvas x:Name="CursorLayer"/>
</Grid>