2013-04-28 57 views
0

我開發了視頻使用時間軸用戶控制的一部分。這裏是我的作品照片: enter image description here更新只是一個usercontrol

這裏我有問題。當currentTime更改時,我必須更新UI。但是當我使用this.Invalidate();它刷新了整個控制。但我想更新指針(灰色背景中的白線)。因爲它會導致控制在非常微小的時間變化中一遍又一遍地眨眼。 如何更新指針? 這裏是我的OnPaint方法

private void OnPaint(object sender, System.Windows.Forms.PaintEventArgs e) 
    { 
     int width = this.Width; 
     int height = this.Height; 
     int Floor = height - FloorDistance; 
     Pen SecPen = new Pen(SecColor); 
     Pen MinPen = new Pen(MinColor); 
     SolidBrush TimeLineBrush = new SolidBrush(Color.Gray); 
     StringFormat stringFormat = new StringFormat(); 
     SolidBrush TimesolidBrush = new SolidBrush(TimeColor); 
     SolidBrush BackBrush = new SolidBrush(TimlineBackColor); 
     SolidBrush PointerBrush = new SolidBrush(PointerColor); 
     stringFormat.FormatFlags = StringFormatFlags.DirectionVertical; 
     switch (Zoom) 
     { 
      case ZoomLEvel.Quarter: 
       width = (int)Math.Ceiling((TotalDuration/900)) * ThickDistance; 
       break; 
      case ZoomLEvel.Minute: 
       width = (int)Math.Ceiling((TotalDuration/60)) * ThickDistance; 
       break; 
      case ZoomLEvel.Secound: 
       width = (int)Math.Ceiling(TotalDuration) * ThickDistance; 
       break; 
      case ZoomLEvel.MiliSecound: 
       width = (int)Math.Ceiling(TotalDuration * 10) * ThickDistance; 
       break; 
     } 
     width += 11; 
     this.Width = width; 

     e.Graphics.FillRectangle(TimeLineBrush, 0, Floor, width, 3); 
     e.Graphics.FillRectangle(BackBrush, 0, 0, width, height - FloorDistance); 

     int x = ThickDistance; 
     int step = 0; 
     while (x <= width - ThickDistance) 
     { 
      if (step % 5 == 0) 
      { 
       e.Graphics.DrawLine(MinPen, x, Floor, x, Floor - _MinHeight); 
       // print time 
       string time = ""; 
       double totalSecounds = 0; 
       PointF pointF = new PointF(x - 8, Floor + 5); 


       switch (Zoom) 
       { 
        case ZoomLEvel.Quarter: 
         totalSecounds = step * 900; 
         break; 
        case ZoomLEvel.Minute: 
         totalSecounds = step * 60; 
         break; 
        case ZoomLEvel.Secound: 
         totalSecounds = step; 
         break; 
        case ZoomLEvel.MiliSecound: 
         totalSecounds = step/10d; 
         break; 
       } 

       time = (new TimeSpan(0, 0, 0, (int)totalSecounds, (int)(step % 10) * 100)).ToString(@"hh\:mm\:ss\:fff"); 
       e.Graphics.DrawString(time, this.Font, TimesolidBrush, pointF, stringFormat); 

      } 
      else 
       e.Graphics.DrawLine(SecPen, x, Floor, x, Floor - _SecHeight); 
      x += ThickDistance; 
      step++; 
     } 
     int PointerTime = 0;//(int)Math.Floor(CurrentTime); 
     int pointerX = 0; 
     switch (Zoom) 
     { 
      case ZoomLEvel.Quarter: 

       PointerTime = (int)Math.Floor(CurrentTime/900); 
       pointerX = PointerTime * ThickDistance; 
       break; 
      case ZoomLEvel.Minute: 
       PointerTime = (int)Math.Floor(CurrentTime/60); 
       pointerX = PointerTime * ThickDistance; 
       break; 
      case ZoomLEvel.Secound: 
       PointerTime = (int)Math.Floor(CurrentTime); 
       pointerX = PointerTime * ThickDistance; 
       break; 
      case ZoomLEvel.MiliSecound: 
       PointerTime = (int)Math.Floor(CurrentTime * 10); 
       pointerX = PointerTime * ThickDistance; 
       break; 
     } 
     pointerX += 5; 
     e.Graphics.FillRectangle(PointerBrush, pointerX, 0, 2, height - FloorDistance); 
    } 

回答

2

Invalidate()方法的重載接受一個定義要刷新的區域Rectangle類型參數,稱爲剪輯矩形。你應該通過指針的邊界矩形(白線,可能在所有邊填充10個像素)。在您的OnPaint()方法中,您應該檢查e.ClipRectangle屬性以瞭解需要重繪的區域。現在,您的所有繪圖邏輯(e.Graphics。DrawX()調用),你應該首先確認是否該元素與剪切區域相交(可以很容易地使用Rectangle.IntersectsWith()來完成)。如果是這樣,你應該調用DrawX方法,否則你不應該這樣做。

避免閃爍,你應該把你的控制的DoubleBuffered屬性True。實現真正流暢的渲染很長一段路要走。

另外,我看到你在聲明的OnPaint方法很多刷子和筆,而不是使用後處置他們。我認爲很多這些都將被一次又一次的要求,所以你可能要在類級別聲明它們,然後在你的控制Dispose()方法處理掉了。這將爲您節省一些處理,因爲這是一個與視頻相關的應用程序。

希望有所幫助。

+0

感謝兄弟。我會試一試並回來 – 2013-04-28 09:12:12

+0

DoubleBuffered = true;爲我工作。謝謝 – 2013-04-28 09:29:32