【问题标题】:StreamGeometry vs DrawingContext.DrawLine in WPF C#WPF C# 中的 StreamGeometry 与 DrawingContext.DrawLine
【发布时间】:2014-04-11 20:07:41
【问题描述】:

我要实时绘制数百条线。我选择了 Visual Layer 来执行此操作。但我看到这里有两种不同的画线方式。您建议哪一个以获得更好的性能和速度?

1. DrawingContext.DrawLine

public class DrawingTypeOne : FrameworkElement
{
    private readonly VisualCollection _visuals;
    public DrawingTypeOne(double thickness)
    {
        var myPen = new Pen
        {
            Thickness = 1,
            Brush = Brushes.White,
        };
        myPen.Freeze();

        _visuals = new VisualCollection(this);
        var drawingVisual = new DrawingVisual();
        using (var dc = drawingVisual.RenderOpen())
        {
            dc.DrawLine(myPen, new Point(0,0) , new Point(100,100));
            _visuals.Add(drawingVisual);
        }
    }

    protected override Visual GetVisualChild(int index)
    {
        return _visuals[index];
    }

    protected override int VisualChildrenCount
    {
        get
        {
            return _visuals.Count;
        }
    }
}

2。流几何

public class DrawingTypeTwo : FrameworkElement
{
    private readonly VisualCollection _visuals;
    public DrawingTypeTwo()
    {
        _visuals = new VisualCollection(this);

        var geometry = new StreamGeometry();
        using (var gc = geometry.Open())
        {
            gc.BeginFigure(new Point(0, 0), true, true);
            gc.LineTo(new Point(100,100), true, false);
        }
        geometry.Freeze();

        var drawingVisual = new DrawingVisual();
        using (var dc = drawingVisual.RenderOpen())
        {
            dc.DrawGeometry(Brushes.Red, null, geometry);
        }

        _visuals.Add(drawingVisual);
    }

    protected override Visual GetVisualChild(int index)
    {
        return _visuals[index];
    }

    protected override int VisualChildrenCount
    {
        get
        {
            return _visuals.Count;
        }
    }
}

【问题讨论】:

  • 为什么不同时尝试它们并回答您自己的问题?
  • 如何将控件的内容设置为来自 StreamGeometry 的 PathFigure?
  • @Vahid 是的,理论上,它比路径信息轻,因为它不支持某些相同的功能集。
  • @Vahid 是的,批量绘图应该有帮助。一般来说,几百行在 WPF 中很容易绘制,但是,无论您如何绘制,都可能不会成为问题。我不会过多地关注优化它,直到/除非它是一个问题。
  • 如果您想要性能,请不要为 100 行创建 100 个视觉效果。只需创建一个视觉对象并在其中绘制这 100 条线。 WPF 将缓存您的绘图,因此您不需要从 FrameworkElement 继承。此外,这就是您将如何获得无需测量的视觉效果并安排支持,这也将为您节省大量时间。

标签: c# wpf performance line drawingcontext


【解决方案1】:

就像我说的,你只需要一个视觉效果,里面就可以有你所有的线条。

看看这个:

首先我们在绘图上下文中定义多个绘图:

class EllipseAndRectangle : DrawingVisual
{
    public EllipseAndRectangle()
    {
        using (DrawingContext dc = RenderOpen())
        {
            // Black ellipse with blue border
            dc.DrawEllipse(Brushes.Black,
                new Pen(Brushes.Blue, 3),        
                new Point(120, 120), 20, 40); 

            // Red rectangle with green border
            dc.DrawRectangle(Brushes.Red,
                new Pen(Brushes.Green, 4),    
                new Rect(new Point(10, 10), new Point(80, 80))); 
        }
    }
}

这是承载所有绘图的一个特殊视觉或元素:

public class EllAndRectHost : FrameworkElement
{
    private EllipseAndRectangle _ellAndRect = new EllipseAndRectangle();

    // EllipseAndRectangle instance is our only visual child
    protected override Visual GetVisualChild(int index)
    {
        return _ellAndRect;
    }

    protected override int VisualChildrenCount
    {
        get
        {
            return 1;
        }
    }
}

这就是您可以在 XAML 中使用所有这些东西的方式:

<local:EllAndRectHost Margin="30" ... />

我说的是可以继承的 DrawingVisual 类,而不是为 100 行创建 100 个视觉效果。

关于您的问题,第一种方法更快。因为第二种方法最终会做同样的事情,第一种方法只是包装得很好。 DrawLine 是最低端。你不能比DrawLine 更深入。 DrawGeometry 正在调用 DrawLine 和其他一些内部信息。

【讨论】:

  • 其实我就是按照上面的方法做的。我的循环在Using 内运行。不继承 FrameworkElement 怎么样?我读到我也可以继承UIElement
  • 顺便说一下,您能否在StreamGeometry vs DrawingContext.DrawLine 上附加您的评论。它在 cmets 中丢失了。
  • 在您的代码中,您有这一行:_visuals.Add(drawingVisual); 在我看来,您将每一行添加到 VisualCollection。然后您可以使用_visuals[index]; 访问它们,无需拥有 100 个绘图视觉对象,您只需拥有一个即可。 :)
  • 是的,您可以从 UIElement 甚至 Visual 继承。您只需要一台主机和一台带有所有图纸的视觉装置。 Grid、StackPanel、Canvas 可以是您的所有主机。 WPF 中的一切都是视觉对象。
  • 始终认为自己是专业人士。永远不要声称它是一个错误。将其作为功能出售。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-28
  • 1970-01-01
  • 1970-01-01
  • 2013-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多