在
WPF UI中,我有通过bezier路径连接的节点,如下所示:
当用户拖动节点时,需要实时更新连接路径.但是,我注意到一些减速(特别是如果一个节点连接到许多其他节点,或者一次拖动多个节点).我描述了它,主要问题似乎在这里:
这是每次更改源属性或目标属性时调用的函数.每当任何控制点发生变化时,构成路径的几何体似乎在内部重新生成.也许如果有一种方法可以阻止几何体重新生成,直到设置了所有相关的依赖属性之后?
编辑: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