En una interfaz de usuario WPF tengo nodos conectados por caminos de Bezier, así:actualización WPF PathGeometry es _SLOW_
Cuando el usuario arrastra un nodo alrededor de, las vías de conexión necesitan ser actualizados en real hora. Sin embargo, he notado cierta desaceleración (especialmente si un nodo está conectado a muchos otros, o múltiples nodos se están arrastrando a la vez). Me perfilado, y el principal problema parece ser aquí:
Esta es la función que se llama cada vez que se cambia la propiedad ya sea de origen o destino. La geometría que compone la ruta parece regenerarse internamente cada vez que cambia alguno de los puntos de control. ¿Tal vez si hubiera una manera de evitar que la geometría se regenere hasta después de que se hayan establecido todas las propiedades de dependencia relevantes?
EDIT: solución Mart utilizar StreamGeometry aceleró hacia arriba de manera exponencial; la función no está cerca de un cuello de botella. Un pequeño Reflecting sugiere que PathGeometry usa StreamGeometry internamente, y cada vez que se cambia cualquiera de las propiedades de dependencia, se vuelve a calcular StreamGeometry. Así que de esta manera se corta al intermediario. El resultado final es:
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, true, false);
}
}
El código fuente completo del proyecto está disponible en http://zeal.codeplex.com para los curiosos.
Gracias; ¡cambiar a StreamGeometry pareció resolver el problema! –