0

我想渲染一条包含数百个点的贝塞尔曲线。这条曲线不需要以任何方式进行测试或交互,所以我想我会尝试一个 Visual,因为它似乎是最轻的。

但是使用下面的代码,为什么会导致应用程序的其余部分运行缓慢?例如,窗口大小调整非常慢。

我只是在寻找在没有任何输入处理功能的情况下渲染曲线的最有效方法(即使使用此示例,您也可以连接到 MouseOver 事件,它只会在您的光标实际位于线条上方时触发,所以它看起来我仍在为此付费(设置 IsHitTestVisiable 似乎对性能没有帮助))

public class VisualHost : FrameworkElement
{
    VisualCollection _children;

    public VisualHost()
    {
        _children = new VisualCollection(this);
        _children.Add(CreateDrawingVisualRectangle());

    }

    DrawingVisual CreateDrawingVisualRectangle()
    {
        var drawingVisual = new DrawingVisual();
        var drawingContext = drawingVisual.RenderOpen();

        var geometry = new StreamGeometry();
        using (var ctx = geometry.Open())
        {
            ctx.BeginFigure(new Point(0, 0), false, false);
            var r = new Random();

            for (int i = 0; i < 500; ++i)
            {
                var p1 = new Point(r.Next(0, 1000), r.Next(0, 1000));
                var p2 = new Point(r.Next(0, 1000), r.Next(0, 1000));
                ctx.QuadraticBezierTo(p1, p2, true, false);
            }
        }

        geometry.Freeze();

        drawingContext.DrawGeometry(null, new Pen(Brushes.Red, 1), geometry);
        drawingContext.Close();

        return drawingVisual;
    }

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

    protected override Visual GetVisualChild(int index)
    {
        if (index < 0 || index >= _children.Count)
        {
            throw new ArgumentOutOfRangeException();
        }

        return _children[index];
    }
}

public partial class MainWindow : Window
{
    public MainWindow()
    {
        Content = new VisualHost();
    }
}
4

1 回答 1

2

您可以使用 aBitmapCache创建一个缓存DrawingVisual...渲染的位图,这样当您FrameworkElement无效时(由于大小调整),缓存的位图用于提供“视觉位”,而不是必须的较慢路线再次在“DrawingVisual”内渲染绘图指令(即在绘图上下文中描述StreamGeometry的内容)。

   DrawingVisual CreateDrawingVisualRectangle()
    {
        var drawingVisual = new DrawingVisual();
        var drawingContext = drawingVisual.RenderOpen();

        var geometry = new StreamGeometry();
        using (var ctx = geometry.Open())
        {
            ctx.BeginFigure(new Point(0, 0), false, false);
            var r = new Random();

            for (int i = 0; i < 500; ++i)
            {
                var p1 = new Point(r.Next(0, 1000), r.Next(0, 1000));
                var p2 = new Point(r.Next(0, 1000), r.Next(0, 1000));
                ctx.QuadraticBezierTo(p1, p2, true, false);
            }
        }

        geometry.Freeze();

        drawingContext.DrawGeometry(null, new Pen(Brushes.Red, 1), geometry);
        drawingContext.Close();

        drawingVisual.CacheMode = new BitmapCache();

        return drawingVisual;
    }
于 2014-03-01T18:36:49.450 回答