2011-03-24 60 views
1

我上有氣勢面板(用於平滑滾動)的移動應用程序用戶界面的工作進行UI更新和我目前正在更新UI durring通過使用下面的代碼平滑滾動:在一個循環中

private void scrollKinetic() 
{ 
    while (_curState == States.KineticScroll) 
    { 
     // This gets how far the panel will move with the current velocity, then updates the velocity according to the current friction. 
     var distY = GetDistance(scrVelocity.Y); 
     var distX = GetDistance(scrVelocity.X); 

     if (distY + distX <= 0) // Friction will eventually make distX and distY both 0 
     { 
      _curState = States.Idle; 
      Invalidate(); 
      break; 
     } 

     // CalculatePosition will move the panel accordingly. 

     CalculatePosition(distY, scrVelocity.Y, false); 
     CalculatePosition(distX, scrVelocity.X, true); 

     Invalidate(); 
     friction++; 
     Application.DoEvents(); 
    } 
} 

正如你所看到的,Application.DoEvents();正在飼養它的醜陋的頭!我想擺脫它,但我想不出任何方式來循環和更新用戶界面。任何幫助/想法都會很棒!

我在.net CF上這樣做,但我認爲這是一個設計問題,所以我認爲平臺不會太重要。

+0

無法從scrVelocity生成任何事件?然後使用計時器。 – 2011-03-24 04:13:15

回答

1

您可以嘗試並刪除循環(以及所有App.DoEvent調用),在您的OnPaint()方法中調用KineticScroll,然後在您的KineticScroll方法中調用Invalidate()。

我看到你有某種狀態跟蹤的,所以你可以這樣說:

if(_curState == States.KineticScroll) 
    KineticScroll(); 
在您的OnPaint()方法

,這樣,你只把它當你的狀態是approprate。

基本上,你的循環從本地while循環轉到:OnPaint -> KineticScroll -> Invalidate -> OnPaint...etc這樣你就可以得到相同的循環,而不需要撥打DoEvents!

1

我會創建一個像「遊戲循環」一樣的計時器 - 每秒執行x次。
我還會記錄自上次調用以來經過了多少時間,以便您可以根據該時間過去計算需要移動多少時間。爲了獲得額外的性能,定時器只有在運動時才能啓動和停止。

根據您使用的定時器類型,您可能需要將您的UI更新調用封送回UI線程。

+0

我最初做了一個帶有Timer的版本,但它感覺像是在拼圖...我最初設置的時間間隔爲30 fps,但它非常不穩定,然後我將刷新時間間隔設置爲10 fps,而且稍微好一些,但是仍然不如DoEvent循環那樣流暢。什麼是使定時器更流暢的好方法? – 2011-03-24 04:36:49

+0

您是否跟蹤自定時器上次觸發以來已經過了多長時間並移動距離= vel *時間?定時器不會在預定的時間發出回調。 – foson 2011-03-24 13:53:33