簡體   English   中英

如何在進度欄中顯示圖像加載進度c#

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM