2017-06-13 18 views
1

我有5個數字降序排序的數組:{289,151,69,27,6}:製作增量完成在同一時間

int[] sortedArray = new int[] { 289, 151, 69, 27, 6 }; 

和5 progressbars在窗體上。 每一個進度條的最大值= sortedArray [X]

因此,例如:

progressBar0.MaxValue = 289; //First element of array 

progressBar1.MaxValue = 151; //2nd 

progressBar3.MaxValue = 69; // etc... 

我想達成什麼是使所有progressbars增量,直到它們各自的MaxValue,而且使光潔度同時

我開始爲每個數組元素創建一個新的線程。但我找不到算法,以使它們一起完成。我想用TimeSpan實現一些東西。因此,例如:

所有progressbars需要5秒..

內是他們的MaxValue我怎麼能這樣做?

+1

您可以根據達到5秒鐘的時間量來計算當前值並設置該值。 –

+1

@MightyBadaboom實際上使用你的%計算思路,他不需要5秒的限制,如果你將每個值分解成100的等級,相同數量的增量將使它們全部達到100(值可以被舍入最多佔小數)。 –

+0

爲什麼你需要使用線程?使用一個'定時器'[如圖所示](https://stackoverflow.com/questions/7259511/increase-a-progressbar-with-timer-in-winforms)。你只需要根據最大值計算'Interval'屬性。例如:'timer.Interval = 5000/289' –

回答

2

當您試圖在一段時間內增加它們時,您需要做的是制定一個介於0和1之間的因子,表明您完成的距離有多近(基於您開始以來已經過了多長時間)

某處記錄開始時間。 var startTime = DateTime.UtcNow;在你的更新代碼

那麼做到這一點

var elapsedTime = DateTime.UtcNow - startTime; //How long as elapsed 
int progress = elapsedTime.TotalSeconds/5.0; //Small number/a large number is always 0..1 
if (progress > 1) 
    progress = 1; 

則進度條顯示基於0..MaxValue的規模,而不是0..1自己的進步,所以你只要乘以目前的進度因素通過progressBar.MaxValue

someProgressBar.Value = (int)Math.Ceiling(someProgressBar.MaxValue * progress); 

這是完全一樣的工作了百分比(每百),您只需通過100這就是你的工作了,順便百分比乘以0..1因子(smallNumber/bigNumber)* 100.

PS:如果您按照我的建議使用絕對時間,那麼您的進度條將始終在正確的時間完成。在循環中添加小增量(例如,在定時器中)的問題是,如果應用程序繁忙/滯後,那麼定時器將完成得太晚。

+0

偉大的這是我一直在尋找!謝謝 :) – user3673720

1

這只是按比例增加它們的一個例子。

因此,讓我們說,出於參數的原因,他們都將增加5倍。簡單地將每個最大值除以5,並按每個步長遞增該量。

int[] sortedArray = new int[] { 289, 151, 69, 27, 6 }; 
var incrementCount = 5.0; 
int incrementAmount = sortedArray.Select(x => Math.Ceil((float)x/incrementCount)).ToArray(); 

您現在有一個數組,每個進度條都有相應的增量步長。

0

您需要找到一些地方編寫代碼來增加進度條的值。

一個計時器是一個很好的選擇,與Thread你不能有辦法定期更新進度條。

現在讓我們來創建一個計時器,它每秒鐘都有一個滴答滴答,當計時器滴答時,我們更新進度條。我們選擇System.Windows.Forms.Timer,因此Tick事件處理程序在UI線程上運行。

System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer(); 
myTimer.Interval = 1000; 
myTimer.Tick += (sender, e) => UpdateProgressBars(); 
myTimer.Start(); 

下一步就是計算每個進度條的值。

對於第一個ProgressBar,在第一個勾號處,值將是289/5;在第二個時間點,它將是(289/5 * 2)。

所以UpdateProgressBars方法是這樣的

int counter = 0; //the counter for tick event 
private void UpdateProgressBars(object sender, EventArgs e) 
{ 
    counter++; 
    progressbar1.Value = sortedArray[0] * counter/5; 
    progressbar2.Value = sortedArray[1] * counter/5; 
    ... 
} 
0

我只考慮在這裏一個值,但該解決方案能夠輕鬆地擴展到多個值。

輸入:

  • 最大值:V_max
  • 時間跨度,其中在所述端部的進展值應等於V_maxtimespan

進展值:

  • V_progress

助手:

  • 一個StopWatch跟蹤的經過時間:stopwatch
  • 一個System.Timers.Timer執行每10ms定期更新:timer

當秒錶的經過時間達到輸入時間間隔,停止更新並將V_progress設置爲V_max。否則根據經過的時間計算V_progress作爲V_max的一小部分。

var V_max = 254; 
var V_progress = 0.0; 
var timespan = new TimeSpan(0, 0, 0, 5, 0); 
var stopwatch = new Stopwatch(); 
var timer = new System.Timers.Timer(10); 
timer.Elapsed += (sender, e) => 
{ 
    var elapsedMs = stopwatch.Elapsed.TotalMilliseconds; 
    var percentage = stopwatch.Elapsed.TotalMilliseconds/timespan.TotalMilliseconds; 
    if (percentage >= 1.0) 
    { 
     timer.Stop(); 
     stopwatch.Stop(); 
     percentage = 1.0; 
    } 
    // probably dispatch this assignment to the UI thread for the actual code 
    V_progress = percentage * V_max; 
    // test output 
    Console.WriteLine(V_progress); 
}; 


stopwatch.Start(); 
timer.Start(); 
0

讓自己變得簡單 - 使用微軟的Reactive Framework(NuGet「System.Reactive.Windows.Forms」(假設這是Windows窗體))。那麼你可以這樣做:

ProgressBar[] progressBars = new ProgressBar[] { /* pbs here */ }; 
int[] sortedArray = new int[] { 289, 151, 69, 27, 6 }; 

var updates = 100; 
Observable 
    .Interval(TimeSpan.FromSeconds(5.0/updates)) 
    .Take(updates) 
    .Select(n => sortedArray.Select(x => x * ((int)n + 1)/updates).ToArray()) 
    .ObserveOn(this) 
    .Subscribe(x => 
    { 
     for (var i = 0; i < sortedArray.Length; i++) 
     { 
      progressBars[i].Value = x[i]; 
     } 
    }); 

我測試過這段代碼,它工作得很好,據我所知。