[英]How Do I Show Image Loading Progress in progress-bar c#
我想知道如何在win窗體的進度欄中顯示圖像加載進度。
我的代碼是
private void Form2_Load(object sender, EventArgs e)//load form and get profile and avatar
{
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
label2.Text = "Avatar Loaded";
}
private void backgroundWorker1_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)//showing progress
{
if (InvokeRequired)
{
BeginInvoke(new Action(() => backgroundWorker1_ProgressChanged(sender, e)));
}
else
{
if (progressBarX1.Value != e.ProgressPercentage)
{
progressBarX1.Value = e.ProgressPercentage;
progressBarX1.Refresh();
}
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)//loading avatar
{
WebClient wc = new WebClient();
Stream stream = wc.OpenRead("http://avatar.nimbuzz.com/getAvatar?jid=" + textBox1.Text);
pictureBox1.Image = (Image.FromStream(stream));
}
圖像成功加載,但在進度欄中未顯示任何進度
您的代碼的問題在於,在輔助線程的上下文中調用了backgroundWorker1_ProgressChanged(),但UI更新只能在UI線程(主線程)內完成。 在您的情況下,您必須致電:
progressBarX1.Value = e.ProgressPercentage;
在UI線程中。 有很多方法可以執行此操作,但是一個簡單的方法是使用InvokeReqzired()檢查您是否在UI線程中,然后再不調用BeginInvoke()將該命令的執行發送到UI- / main-線。 以下應該可以解決問題:
private void backgroundWorker1_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
if (InvokeRequired)
{
BeginInvoke(new Action(() => backgroundWorker1_ProgressChanged(sender, e)));
}
else
{
progressBarX1.Value = e.ProgressPercentage;
}
}
更新:我還將更改:
backgroundWorker1.RunWorkerAsync();
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
至:
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
backgroundWorker1.RunWorkerAsync();
因此,在開始異步工作之前,已分配(因此就位)了progress事件。 否則,您可能會錯過進度呼叫。
更新2:
您還需要以下行在UI線程中執行:
pictureBox1.Image = (Image.FromStream(stream));
為此,請使用BackgroundWorker的Completed事件,並使用result參數低音處理圖像數據。 然后在事件處理程序中使用InvokeRequired()和BeginInvoke(),就像在Progress事件中一樣。
Uodate 3:
記住保持不變是個好習慣,因為您不會因為未在UI線程中調用UI東西而崩潰;-)
嘗試通過調用以下命令來強制重畫控件:
progressBarX1.Refresh();
(就在您為其分配了新值之后)。
因此,progress事件中的代碼如下所示:
private void backgroundWorker1_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
if (InvokeRequired)
{
BeginInvoke(new Action(() => backgroundWorker1_ProgressChanged(sender, e)));
}
else
{
if (progressBarX1.Value != e.ProgressPercentage)
{
progressBarX1.Value = e.ProgressPercentage;
progressBarX1.Refresh();
}
}
}
如果仍然不起作用,請檢查您的主/ UI線程是否未阻塞或完全繁忙。
更新4:
只是要確保:您需要在后台工作程序上啟用進度報告,並在backgroundWorker1_DoWork()中不時調用其ReportProgress()方法。 有關使用BackgroundWorker的更多信息,請參見下面的MS教程: http : //msdn.microsoft.com/zh-cn/library/cc221403(v=vs.95).aspx
在后台工作人員上啟用進度報告:
backgroundWorker1.WorkerReportsProgress = true;
或使用表單設計器並將屬性WorkerReportsProgress設置為True。 然后,您仍然需要不時地調用backgroundWorker1.ReportProgress()。
更新5:
好的,讓我們嘗試一下。 我已經檢查了MS的一些參考文檔,因此,在后台工作程序ProgressChanged和Completed事件的情況下,您不需要BeginInvoke()它們,因為MS已經為您完成了此操作。
private void Form2_Load(object sender, EventArgs e)
{
getto();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.ProgressChanged -= backgroundWorker1_ProgressChanged;
backgroundWorker1.ProgressChanged += backgroundWorker1_ProgressChanged;
backgroundWorker1.RunWorkerCompleted -= backgroundWorker1_Completed;
backgroundWorker1.RunWorkerCompleted += backgroundWorker1_Completed;
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
using (var wc = new WebClient())
{
wc.DownloadProgressChanged += (sender, e) => backgroundWorker1.ReportProgress(sender, e);
using (var stream = wc.OpenRead("http://avatar.nimbuzz.com/getAvatar?jid=" + textBox1.Text))
{
e.Result = (Image.FromStream(stream));
}
}
}
private void backgroundWorker1_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
progressBarX1.Value = e.ProgressPercentage;
progressBarX1.Refresh();
}
private void backgroundWorker1_Completed(object sender, DoWorkEventArgs e)
{
pictureBox1.Image = e.Result;
}
好吧,我將使用WebClient中的ProgressChanged事件來獲取下載進度實際距離的結果。 然后,您將無法從backgroundworker的線程中保存它,因此在擁有文件時必須執行此操作。
更新
private BackgroundWorker bgw;
private void Form1_Load(object sender, EventArgs e)
{
bgw = new BackgroundWorker();
bgw.DoWork += bgw_DoWork;
bgw.WorkerReportsProgress = true;
bgw.RunWorkerCompleted += bgw_RunWorkerCompleted;
bgw.ProgressChanged += bgw_ProgressChanged;
bgw.RunWorkerAsync();
}
void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
pictureBox1.Image = (Image)e.Result;
}
void bgw_DoWork(object sender, DoWorkEventArgs e)
{
WebClient wc = new WebClient();
wc.DownloadProgressChanged += wc_DownloadProgressChanged;
Stream stream = wc.OpenRead("" + textBox1.Text);
e.Result = (Image.FromStream(stream));
}
void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
bgw.ReportProgress(e.ProgressPercentage);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.