0

我有一个带有一些图像的画布,并且我也在使用 DrawGeometry 来绘制一个在时间流逝时正在填充的圆圈。

这就是我在 DrawingContext 中绘制圆圈的方式:

protected override void OnRender(DrawingContext drawingContext)
{
    base.OnRender(drawingContext);
    MyUtils.RenderProgressClock(drawingContext, clockPosition, 50, gameTime / totalTime);
}

并调用 InvalidateVisual(); 调用它。

但是这样做我的圈子在我的图像后面,我看不到它,我怎么能在它们前面画呢?

我对 WPF 完全陌生,这让我很难过....

这是请求的其他方法代码:

 private static PathGeometry GetClockGeometry(Point position, double percentage, double radius)
        {
            const double innerFactor = 0.90;
            double innerRadius = radius * innerFactor;

            PathGeometry pie = new PathGeometry();

            PathFigure pathFigure = new PathFigure();
            pathFigure.StartPoint = new Point(0, -innerRadius);
            pathFigure.IsClosed = true;

            if (percentage > kMaxClockPercentage)
            {
                percentage = kMaxClockPercentage;
            }
            double angle = 360.0 * percentage;

            // Starting Point
            LineSegment inOutLine = new LineSegment(new Point(0, -radius), true);

            // Arc
            ArcSegment outerArc = new ArcSegment();

            outerArc.IsLargeArc = angle >= 180.0;
            outerArc.Point = new Point(Math.Cos((angle - 90) * Math.PI / 180.0) * radius, Math.Sin((angle - 90) * Math.PI / 180.0) * radius);
            outerArc.Size = new Size(radius, radius);
            outerArc.SweepDirection = SweepDirection.Clockwise;

            LineSegment outInLine = new LineSegment(new Point(outerArc.Point.X * innerFactor, outerArc.Point.Y * innerFactor), true);

            ArcSegment innerArc = new ArcSegment();
            innerArc.IsLargeArc = angle >= 180.0;
            innerArc.Point = pathFigure.StartPoint;
            innerArc.Size = new Size(innerRadius, innerRadius);
            innerArc.SweepDirection = SweepDirection.Counterclockwise;

            pathFigure.Segments.Add(inOutLine);
            pathFigure.Segments.Add(outerArc);
            pathFigure.Segments.Add(outInLine);
            pathFigure.Segments.Add(innerArc);

            pie.Transform = new TranslateTransform(position.X, position.Y);
            pie.Figures.Add(pathFigure);

            return pie;
        }
4

2 回答 2

1

好的,现在我对发生的事情有了更好的了解,我发现我的初始答案不会直接对您有用。但是,我也看到你有一点问题。

OnRender 工作方式的一般性质意味着您绘制的内容总是会出现在图像的后面,以及您添加到窗口中的其他内容。

除此之外,您将所有这些用于特定功能(进度时钟)的绘图代码放入窗口本身,这个解决方案感觉有点不对劲。

您可能想探索一些替代方案。

一个简单的方法是创建一个 UserControl 来绘制时钟。该 UserControl 可以具有应填充的 % 的 DependencyProperty。您可以在 UserControl 中使用(大致)相同的 OnRender 代码,或者您可以使用其他一些奇特的方式来实现(我确信在所有 XAML 中都有某种方式可以做到这一点,尽管我不知道它在我的脑海中)。然后,您只需像所有其他图像/控件一样将该时钟放入窗口中。

您也可以创建一个 CustomControl,尽管这需要更多关于 WPF 和资源的知识,以及了解它的工作原理。由于您是 WPF 的新手,所以现在可能有点多。

于 2012-12-20T19:36:55.323 回答
1

您需要向我们展示您的圈子是如何添加到画布中的。

WPF 是一个保留的绘图系统,因此控件出现在它的可视化树中的顺序决定了它们的堆叠顺序。OnRender()真正的意思AccumulateDrawingObjects()是它不直接绘制,它只是创建一组要绘制的对象。

此外,如果对象保持相同大小,则不需要这样做InvalidateVisual(),因为它会导致非常昂贵的重新布局。

More efficient ways to re-render are to use a DependencyProperty with AffectsRender... Or to create a DrawingGroup, add it to the DrawingContext during OnRender(), then anytime later you can DrawingGroup.Open() to change the drawing commands in the DrawingGroup.

于 2017-06-10T08:18:35.620 回答