В WPF UI У меня есть узлы, соединенные Безье путями, например, так:WPF PathGeometry обновление _SLOW_
Когда пользователь перетаскивает узел вокруг, соединительные дорожки должны быть обновлены в реальном масштабе время. Тем не менее, я заметил некоторое замедление (особенно если один узел подключен ко многим другим, или сразу перетаскиваются сразу несколько узлов). Я профилированный, и главная проблема, по-видимому, здесь:
Это функция, которая вызывается каждый раз, либо свойство источника или назначения изменяется. Кажется, что геометрия, составляющая путь, восстанавливается внутренне каждый раз, когда изменяется какая-либо из контрольных точек. Возможно, если бы существовал способ предотвратить регенерацию геометрии до тех пор, пока не будут установлены все соответствующие свойства зависимостей?
EDIT: решение Mart, чтобы использовать StreamGeometry ускорили его в геометрической прогрессии; функция нигде не приближается к узкому месту. Небольшое Reflecting предполагает, что 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, true, false);
}
}
Полный исходный код проекта доступен на http://zeal.codeplex.com для любопытных.
Thanks; переключение на StreamGeometry, похоже, решило проблему! –