2009-11-18 1 views
4

내 자신의 FrameworkElement를 만들고 내 자신의 DrawingVisual 컬렉션 인스턴스를 반환하여 VisualChildrenCount {get;} 및 GetVisualChild (int index)를 재정의합니다. 재정의 OnRender가 있습니다.그리기 시각적 렌더링 속도 향상

이 FrameworkElement에 20-50 DrawingVisuals를 추가합니다. DrawingVisual마다 2000 개의 선 세그먼트가 있습니다. 이러한 점의 논리 값은 0에서 60000 사이입니다 .1 : 1로 확대하면 FrameworkElement의 높이가 60000이되고, 시간은 15 분입니다 !!

렌더링 성능을 어떻게 향상시킬 수 있습니까?

답변

4

이런 종류의 데이터 볼륨의 경우 각 포인트에 대해 단일 PolyLine을 포함하는 GeometryDrawing 및 StreamGeometry를 작성하는 것이 좋습니다. 그런 다음 단일 DrawingGroup에서 이들을 모두 결합하고 단일 DrawingVisual을 사용하여 표시하십시오.

이것은 XAML 다음과 같습니다

<DrawingVisual Drawing="{Binding CurrentDrawing}" /> 

이이 CurrentDrawing 업데이트 할 수있는 코드가 될 것이다 : 당신의 데이터는 별도로 각 GeometryDrawing 객체 저장소를 생성하는 것이 유리할 수있다 변경하는 경우

var group = new DrawingGroup(); 
foreach(var data in myData) 
{ 
    StreamGeometry geo = new StreamGeometry(); 
    using(geoContext = geo.Open()) 
    { 
    geoContext.BeginFigure(myData.StartPoint, false, false); 
    geoContext.PolyLineTo(myData.AdditionalPoints, true, false); 
    } 
    group.Add(new GeometryDrawing 
    { 
    Geometry = geo, 
    Pen = myData.Pen, 
    }); 
} 
CurrentDrawing = group; 
... 

소스 데이터가 변경된 GeometryDrawings 만 다시 작성하면됩니다. 당신은 20 ~ 50 개 데이터의 각 항목을 별도로 그러나 hitTest 필요

업데이트 당신은 당신의 코멘트에 언급

. 이 경우 각각에 대해 별도의 DrawingVisual을 사용하려고합니다. 최적의 성능을 얻기 위해 당신은 DrawingContextRenderOpen()를 사용하는 것이 좋습니다 :

IEnumerable<Visual> BuildVisuals() 
{ 
    return 
    from var data in myData 
    select BuildVisualForData(data); 
} 

void BuildVisualForData(MyDataType data) 
{ 
    var geo = new StreamGeometry(); 
    using(geoContext = geo.Open()) 
    { 
    geoContext.BeginFigure(myData.StartPoint, false, false); 
    geoContext.PolyLineTo(myData.AdditionalPoints, true, false); 
    } 

    var visual = new DrawingVisual(); 
    using(drawingContext = visual.RenderOpen()) 
    { 
    drawingContext.DrawGeometry(null, myData.Pen, geo); 
    } 
    return visual; 
} 
+0

안녕 레이 답변 해 주셔서 감사합니다. –

+0

모든 영상을 강조 표시하려면 hittesting을 사용해야합니다. 만약 하나의 DrawingVisual을 사용하여 그것들을 표시한다면, 아마도 그렇게하지 못할 것이라고 생각합니다. –

+0

이 경우 각 데이터 항목을 자체 DrawingVisual에 배치하고 RenderOpen() 및 DrawingContext를 사용합니다. 나는 이것이 어떻게 행해지는지 보여주는 나의 대답을 편집했다. –

0

나는 모든 비주얼을 강조 hittesting를 사용합니다. 만약 하나의 DrawingVisual을 사용하여 그것들을 표시한다면, 아마도 그렇게하지 못할 것이라고 생각합니다.

이런 종류의 데이터 볼륨의 경우 각 포인트에 대해 단일 PolyLine을 포함하는 GeometryDrawing 및 StreamGeometry를 작성하는 것이 좋습니다. 그런 다음 단일 DrawingGroup에서 이들을 모두 결합하고 단일 DrawingVisual을 사용하여 표시하십시오.

이것은 XAML 다음과 같습니다

<DrawingVisual Drawing="{Binding CurrentDrawing}" /> 

이이 CurrentDrawing 업데이트 할 수있는 코드가 될 것이다 : 당신의 데이터는 별도로 각 GeometryDrawing 객체 저장소를 생성하는 것이 유리할 수있다 변경하는 경우

var group = new DrawingGroup(); 
foreach(var data in myData) 
{ 
    StreamGeometry geo = new StreamGeometry(); 
    using(geoContext = geo.Open()) 
    { 
    geoContext.BeginFigure(myData.StartPoint, false, false); 
    geoContext.PolyLineTo(myData.AdditionalPoints, true, false); 
    } 
    group.Add(new GeometryDrawing 
    { 
    Geometry = geo, 
    Pen = myData.Pen, 
    }); 
} 
CurrentDrawing = group; 
... 

따라서 원본 데이터가 변경된 GeometryDrawings 만 다시 작성해야합니다.