2010-03-06 3 views
8

У меня проблемы с производительностью рисования WPF. Есть много маленьких объектов EllipseGeometry (например, 1024 эллипса), которые добавляются к трем отдельным GeometryGroups с различными кистями переднего плана. После этого я делаю все это на простом управлении Image. Код:Производительность рисования WPF с большим количеством геометрий

DrawingGroup tmpDrawing = new DrawingGroup(); 
GeometryGroup onGroup = new GeometryGroup(); 
GeometryGroup offGroup = new GeometryGroup(); 
GeometryGroup disabledGroup = new GeometryGroup(); 

for (int x = 0; x < DisplayWidth; ++x) 
{ 
    for (int y = 0; y < DisplayHeight; ++y) 
    { 
     if (States[x, y] == true) onGroup.Children.Add(new EllipseGeometry(new Rect((double)x * EDGE, (double)y * EDGE, EDGE, EDGE))); 
     else if (States[x, y] == false) offGroup.Children.Add(new EllipseGeometry(new Rect((double)x * EDGE, (double)y * EDGE, EDGE, EDGE))); 
     else disabledGroup.Children.Add(new EllipseGeometry(new Rect((double)x * EDGE, (double)y * EDGE, EDGE, EDGE))); 
    } 
} 

tmpDrawing.Children.Add(new GeometryDrawing(OnBrush, null, onGroup)); 
tmpDrawing.Children.Add(new GeometryDrawing(OffBrush, null, offGroup)); 
tmpDrawing.Children.Add(new GeometryDrawing(DisabledBrush, null, disabledGroup)); 
DisplayImage.Source = new DrawingImage(tmpDrawing); 

Он отлично работает, но занимает слишком много времени -> 0.5с на Core 2 Quad,> 2s на Pentium 4. Мне нужно < 0.1s везде. Все эллипсы, как вы можете видеть, равны. Фон управления, где мой DisplayImage, твердый (например, черный), поэтому мы можем использовать этот факт. Я попытался использовать 1024 элемента Ellipse вместо Image с EllipseGeometries, и он работал намного быстрее (~ 0,5 с), но этого недостаточно. Как ускорить его?

С уважением, Олег Еремеев

P.S. Извините за мой английский.

+6

Не нужно извиняться за ваш английский. –

+0

Вы пытались использовать WPF Performance Suit, чтобы узнать, что занимает большую часть времени? – levanovd

+0

Спасибо, levanovd, но я знаю, что мой код неверен, этого достаточно. Я спрашиваю о совершенно другом подходе. –

ответ

4

я оставил свой старый метод рендеринга, но и создание нового EllipseGeometry объекта каждый раз, когда была плохая идея, так что я оптимизировал его таким образом:

for (int x = 0; x < newWidth; ++x) 
{ 
    for (int y = 0; y < newHeight; ++y) 
    { 
     States[x, y] = null; 
     OnEllipses[x, y] = new EllipseGeometry(new Rect((double)x * EDGE + 0.5f, (double)y * EDGE + 0.5f, EDGE - 1f, EDGE - 1f)); 
     OffEllipses[x, y] = new EllipseGeometry(new Rect((double)x * EDGE + 0.5f, (double)y * EDGE + 0.5f, EDGE - 1f, EDGE - 1f)); 
     DisabledEllipses[x, y] = new EllipseGeometry(new Rect((double)x * EDGE + 0.5f, (double)y * EDGE + 0.5f, EDGE - 1f, EDGE - 1f)); 
    } 
} 

// . . . 

DrawingGroup tmpDrawing = new DrawingGroup(); 
GeometryGroup onGroup = new GeometryGroup(); 
GeometryGroup offGroup = new GeometryGroup(); 
GeometryGroup disabledGroup = new GeometryGroup(); 

for (int x = 0; x < DisplayWidth; ++x) 
{ 
    for (int y = 0; y < DisplayHeight; ++y) 
    { 
     if (States[x, y] == true) onGroup.Children.Add(OnEllipses[x, y]); 
     else if (States[x, y] == false) offGroup.Children.Add(OffEllipses[x, y]); 
     else disabledGroup.Children.Add(DisabledEllipses[x, y]); 
    } 
} 

tmpDrawing.Children.Add(new GeometryDrawing(OnBrush, null, onGroup)); 
tmpDrawing.Children.Add(new GeometryDrawing(OffBrush, null, offGroup)); 
tmpDrawing.Children.Add(new GeometryDrawing(DisabledBrush, null, disabledGroup)); 
DisplayImage.Source = new DrawingImage(tmpDrawing); 

При х = 128 и у = 8 она работает очень быстро, даже на системах Pentium III.

1

Даже если я немного опаздываю: This сообщение от Чарльза Петцольда очень помогло в подобном сценарии.

+0

Спасибо за ответ, я могу использовать его в другом проекте в будущем. Мое настоящее решение прекрасно работает, поэтому я думаю, что оставил его как есть. –

Смежные вопросы