WPF中的自定义线条绘制

3
我正在尝试通过覆盖控件的OnRender方法并在给定的DrawingContext上调用DrawLine方法手动绘制WPF中的一条线。我在某个地方读到了这个方法调用不会立即绘制线条,但我无法弄清楚如何使其实际出现。
我尝试使用PathGeometry、LineSegments、Line和Polyline控件的组合。当我画线时,一切都很好,但是当我画折线时,所有东西都变得不正确偏移。
任何关于这个问题的建议都将非常有用。
编辑:
钢笔代码
    private static readonly Pen LinePen = new Pen(new SolidColorBrush(Colors.Green), 3.0d);
    private static readonly Pen WayPointPen = new Pen(new SolidColorBrush(Colors.Gray), 3.0d);

渲染代码

    protected override void OnRender(DrawingContext drawingContext)
    {
        // Draw way points
        this.DrawWayPoints(drawingContext);

        if (mDrawing)
        {
            // Draw current line
            this.DrawCurrentLine(drawingContext);
        }
    }

    private void DrawCurrentLine(DrawingContext context)
    {
        if(mStartPoint.HasValue && mEndPoint.HasValue)
        {
            // Draw the line
            context.DrawLine(LinePen, mStartPoint.Value, mEndPoint.Value);
        }
    }

    private void DrawWayPoints(DrawingContext context)
    {
        if (mWayPoints.Count < 2)
        {
            return;
        }

        // Draw all points
        for (int i = 0; i < mWayPoints.Count - 1; i++)
        {
            var start = mWayPoints[i];
            var end = mWayPoints[i + 1];

            // Draw the line
            context.DrawLine(WayPointPen, start, end);
        }
    }

编辑

测试项目:http://dl.dropbox.com/u/12763956/DrawingTest.zip (使用Visual Studio 2010编写)

使用方法: - 在凸起区域内左键单击以将点添加到列表中。 - 右键单击以结束绘制并清除点。

注意:自定义绘制的线条(在OnRender重写中)不会显示。


1
我使用OnRender绘制线条并且显示正常。您能否提供示例代码,这样我可以看看您做错了什么? - Ed Bayiates
我已经添加了我正在使用的渲染代码。它包含在一个WPF控件中。我尝试过在控件内没有内容和带有画布元素。我还进行了调试,以确保对DrawLine的调用实际上被触发了,而且它们确实被触发了。 - Samuel Slade
抱歉回复晚了——我在骑摩托车。你的代码看起来完全没问题。你可以使用Debug.WriteLine来获取你尝试绘制线条的具体点。如果它们超出了边界,那么就不会出现线条。 - Ed Bayiates
我非常确定这些值在控件的范围内,因为每当单击鼠标左键时,我只是使用鼠标相对于控件的位置。该控件的宽度为800,高度为480,并且所有点击都在其中注册,并给出了在这些范围内的位置。 - Samuel Slade
你仍应添加Debug.WriteLine调用并进行100%的检查。这是我现在能想到的唯一可能性——代码应该可以工作——但如果没有你正在使用的数据,我无法模拟你的调用。 - Ed Bayiates
我已经添加了一个快速制作的测试项目,以重现我的问题,这样你就可以直接看到我的问题了。 - Samuel Slade
1个回答

2
实际上这里有两个问题。第一个是您的Canvas背景会覆盖您在DrawingControl上绘制的任何内容。因此,如果将Canvas背景设置为透明,您可以暂时解决此问题。
第二个问题是您需要在向集合中添加点之后调用InvalidateVisual以强制重新绘制。
您可能需要添加另一个控件来出现在Canvas的顶部,并在那里渲染线条。或者您需要在DrawingControl.OnRender方法中自己渲染背景。

我已经实施了这些更改,但仍然没有成功。如果您希望重新检查更改,我已更新链接。我还在OnRender重写中设置了断点,以确保它实际上被调用。 - Samuel Slade
@Slade - 确保执行“全部重建”。对我来说,更改也没有立即生效,直到我执行了这个操作。我在AddPoint方法的末尾添加了InvalidateVisual调用。不过我会检查你的更新的。 - CodeNaked
1
@Slade - 这次 DrawingControl.Background 遮盖住了线条。你需要手动渲染它。基本上,你正在渲染你的 UserControl,它有一些子视觉元素以及你的内容。其中一个子视觉元素是 Border,用于渲染 Background/BorderBrush。即使它在 ControlTemplate 中,它仍然出现在 DrawingControl 的顶部。 - CodeNaked
@Slade - 要了解我的意思,请在 OnRender 中设置断点。当它命中时,在 Watch 窗口中添加 this。然后单击右侧的放大镜。然后在可视化树中深入挖掘,以查看出现在 DrawingControl 渲染的任何内容上方的所有元素。 - CodeNaked
那就是我的问题所在!背景原因。非常感谢! - Samuel Slade

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接