微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – WPF PathGeometry更新是_SLOW_

WPF UI中,我有通过bezier路径连接的节点,如下所示:

It might be… atomic http://nv3wrg.blu.livefilestore.com/y1pIGBd33lCC6lF-9H0MqgnL40BdNEoEemZDENzgpEI1IL2j4B-qb3qS3WlxMSys28IjqNngR7mdfvQBnPzerf4cFJQj9VqHBh4/acurve.png?psid=1

用户拖动节点时,需要实时更新连接路径.但是,我注意到一些减速(特别是如果一个节点连接到许多其他节点,或者一次拖动多个节点).我描述了它,主要问题似乎在这里

Proof I actually used a profiler,so please don’t be all like “OMG,premature opiumzation; you are DEMON!!” http://nv3wrg.blu.livefilestore.com/y1pjRfQYuN57yei5qdUxW4Dlh4vVCzPy8TcfEzlw_8cUicfOR6BwHCTntcQbQUspRAgBdKcItC0ZcEJbIWMKaYrCtDMOtCBKB4g/profile.png?psid=1

这是每次更改源属性或目标属性调用函数.每当任何控制点发生变化时,构成路径的几何体似乎在内部重新生成.也许如果有一种方法可以阻止几何体重新生成,直到设置了所有相关的依赖属性之后?

编辑:Mart使用StreamGeometry的解决方案以指数方式加速;功能无处接近瓶颈.一点反映表明PathGeometry在内部使用StreamGeometry,每次更改任何依赖项属性时,都会重新计算StreamGeometry.所以这种方式就是切断了中间人.最终结果是:

private void onRouteChanged()
{
    Point src = Source;
    Point dst = Destination;
    if (!src.X.isValid() || !src.Y.isValid() || !dst.X.isValid() || !dst.Y.isValid())
    {
        _shouldDraw = false;
        return;
    }

    /*
        * The control points are all laid out along midpoint lines,something like this:
        * 
        *   -------------------------------- 
        *  |          |          |          |
        *  |   SRC    |    CP1   |          |
        *  |          |          |          |
        *   -------------------------------- 
        *  |          |          |          |
        *  |          |    MID   |          |
        *  |          |          |          |
        *   ------------------------------- 
        *  |          |          |          |
        *  |          |    CP2   |    DST   |
        *  |          |          |          |
        *   -------------------------------- 
        *   
        * This causes it to be horizontal at the endpoints and vertical
        * at the midpoint.
        */

    double mx = (src.X + dst.X) / 2;
    double my = (src.Y + dst.Y) / 2;
    Point mid = new Point(mx,my);
    Point cp1 = new Point(mx,src.Y);
    Point cp2 = new Point(mx,dst.Y);

    _geometry.Clear();
    _shouldDraw = true;
    using(StreamGeometryContext ctx = _geometry.open())
    {
        ctx.Beginfigure(src,false,false);
        ctx.QuadraticBezierTo(cp1,mid,true,false);
        ctx.QuadraticBezierTo(cp2,dst,false);
    }
}

该项目的完整源代码可在http://zeal.codeplex.com获得好奇.

解决方法

1-我会尝试使用StreamGeometry:
StreamGeometry streamGeo = new StreamGeometry();
        Stopwatch sw = new Stopwatch();
        sw.Start();
        for (int i = 0; i < 10000; i++)
        {
            streamGeo.Clear();
            var ctx = streamGeo.open();
            ctx.Beginfigure(new Point(0,0),false);
            ctx.QuadraticBezierTo(new Point(10,10),new Point(10,i),true);
            ctx.Close();
        }
        sw.Stop();
        Console.WriteLine(sw.ElapsedMilliseconds); // For 10k it took 30 ms

它看起来比PathGeometry Pathfigure快得多.

为QuadraticBezierSegment设置Point时,它会重新计算所有内容.这就是为什么它很慢.当它已经添加到几何体时更慢.

2-尝试仅为所有曲线使用1个frameworkelement.检查一下:
Writing More Efficient ItemsControls

原文地址:https://www.jb51.cc/csharp/99033.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐