2014-03-01 32 views
0

我想呈現一個貝塞爾曲線,其中將包含數百個點。這條曲線不需要以任何方式進行測試或交互,所以我認爲我會嘗試一個視覺,因爲這似乎是最輕的重量。自定義繪圖可視化使應用程序緩慢

雖然使用下面的代碼,但爲什麼會導致應用程序的其餘部分緩慢運行?例如,窗口大小調整非常緩慢。

我只是尋找最有效的方式來呈現沒有任何輸入處理功能的曲線(即使這個例子中,你可以連接到MouseOver事件,它只會在你的光標實際上超過行,所以它看起來像我仍然支付那個(設置IsHitTestVisiable似乎並沒有幫助的性能))

public class VisualHost : FrameworkElement 
{ 
    VisualCollection _children; 

    public VisualHost() 
    { 
     _children = new VisualCollection(this); 
     _children.Add(CreateDrawingVisualRectangle()); 

    } 

    DrawingVisual CreateDrawingVisualRectangle() 
    { 
     var drawingVisual = new DrawingVisual(); 
     var drawingContext = drawingVisual.RenderOpen(); 

     var geometry = new StreamGeometry(); 
     using (var ctx = geometry.Open()) 
     { 
      ctx.BeginFigure(new Point(0, 0), false, false); 
      var r = new Random(); 

      for (int i = 0; i < 500; ++i) 
      { 
       var p1 = new Point(r.Next(0, 1000), r.Next(0, 1000)); 
       var p2 = new Point(r.Next(0, 1000), r.Next(0, 1000)); 
       ctx.QuadraticBezierTo(p1, p2, true, false); 
      } 
     } 

     geometry.Freeze(); 

     drawingContext.DrawGeometry(null, new Pen(Brushes.Red, 1), geometry); 
     drawingContext.Close(); 

     return drawingVisual; 
    } 

    protected override int VisualChildrenCount 
    { 
     get { return _children.Count; } 
    } 

    protected override Visual GetVisualChild(int index) 
    { 
     if (index < 0 || index >= _children.Count) 
     { 
      throw new ArgumentOutOfRangeException(); 
     } 

     return _children[index]; 
    } 
} 

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     Content = new VisualHost(); 
    } 
} 

回答

2

你可以使用一個BitmapCache創建緩存DrawingVisual的渲染位圖...因此,當您的FrameworkElement無效(由於大小調整),緩存的位圖用於提供「視覺位」,而不是必須渲染畫筆的較慢路線再次在「DrawingVisual」內部的g指令(即,在drawingcontext中由StreamGeometry描述的內容)。

DrawingVisual CreateDrawingVisualRectangle() 
    { 
     var drawingVisual = new DrawingVisual(); 
     var drawingContext = drawingVisual.RenderOpen(); 

     var geometry = new StreamGeometry(); 
     using (var ctx = geometry.Open()) 
     { 
      ctx.BeginFigure(new Point(0, 0), false, false); 
      var r = new Random(); 

      for (int i = 0; i < 500; ++i) 
      { 
       var p1 = new Point(r.Next(0, 1000), r.Next(0, 1000)); 
       var p2 = new Point(r.Next(0, 1000), r.Next(0, 1000)); 
       ctx.QuadraticBezierTo(p1, p2, true, false); 
      } 
     } 

     geometry.Freeze(); 

     drawingContext.DrawGeometry(null, new Pen(Brushes.Red, 1), geometry); 
     drawingContext.Close(); 

     drawingVisual.CacheMode = new BitmapCache(); 

     return drawingVisual; 
    } 
+0

你可以添加更多的細節,如果明顯不介意,這將有助於嗎? –