2009-12-22 62 views
1

我正在尋找一種方法來創建一個很好的進度條。 我發現了一些我使用過的代碼,如果我使用了一個循環,它的效果很好。但現在我想用它在一個真正的體面的應用程序,它給了我很多麻煩。我有一個應用程序在IMDB上查找數據,所以我連接到IMDB,例如500 movietitles,所以這需要一段時間。所以我想展示一個進度條,其中的每個電影的長度都會隨着它的擡頭而增加,並在movietitle上添加一些額外的信息。c#ProgressBar問題

我用下面的類:

public partial class ProgressDialog : Window, IProgressContext 
{ 
    public ProgressDialog() 
    { 
     InitializeComponent(); 
     IconBitmapDecoder ibd = new IconBitmapDecoder(
     new Uri("IMDB.ML.ico", UriKind.RelativeOrAbsolute), 
     BitmapCreateOptions.None, BitmapCacheOption.Default); 
     this.Icon = ibd.Frames[0]; 
    } 
    public void UpdateProgress(double progress) 
    { 
     Dispatcher.BeginInvoke(DispatcherPriority.Background, 
      (SendOrPostCallback)delegate { Progress.SetValue(ProgressBar.ValueProperty, progress); }, null); 
    } 

    public void UpdateStatus(string status) 
    { 
     Dispatcher.BeginInvoke(DispatcherPriority.Background, 
      (SendOrPostCallback)delegate { StatusText.SetValue(TextBlock.TextProperty, status); }, null); 
    } 

    public void Finish() 
    { 
     Dispatcher.BeginInvoke(DispatcherPriority.Background, 
      (SendOrPostCallback)delegate { Close(); }, null); 
    } 
} 

public interface IProgressContext 
{ 
    void UpdateProgress(double progress); 
    void UpdateStatus(string status); 
    void Finish(); 
} 

這是使用進度IMDB的查找方法,該方法使用一個已經存在的XML列表,以便它只是用於更新數據,而不是增加新的電影:

public static void updateIMDBinfo() 
    { 

     //initialize progressbar 
     ProgressDialog myProgressContext = new ProgressDialog(); 
     myProgressContext.Show();    

     //load old list 
     List<Movie> movieList = XML.getMovieList(); 

     //create new updated list 
     List<Movie> newMovieList = new List<Movie>(); 
     int count = 1; 
     foreach (Movie movie in movieList) 
     { 
      //update progressbar 
      myProgressContext.UpdateProgress((double)count/(double)movieList.Count); 
      myProgressContext.UpdateStatus(String.Format("Updating movie: '{0}' ({1}/{2})", movie.Title, count, movieList.Count)); 

      movie.Link = movie.Link.Substring(movie.Link.IndexOf("http://www.imdb.com/title/") + 26, 9); 

      //this creates a new movie where it looks up the data from imdb 
      newMovieList.Add(new Movie(movie.Title, movie.Link, movie.Path)); 

      count++; 
     } 

     //sort the list 
     newMovieList.Sort((Movie m1, Movie m2) => m1.Title.CompareTo(m2.Title)); 

     //save as xml 
     XML.updateMovieList(newMovieList); 

     //finish progressbar 
     myProgressContext.Finish(); 
    } 

所以,現在當我使用該方法時,它會打開進度條,但酒吧永遠不會填滿,它只是不斷添加電影到列表中,並且在不填充條的情況下查找更新的信息。我認爲在不同的威脅中使用它會解決這個問題?

任何想法?

多謝

編輯:

我使用BackgroundWorker嘗試。我爲我的方法添加了一個後臺工作人員,並返回了一個ReportProgress。我還在我的主類中添加了一個backgroundWorker,它使用該方法和eventhandlers。但它沒有工作。我不是很熟悉不同的威脅。那我該怎麼辦? 我試圖像在這裏:

http://msdn.microsoft.com/en-us/library/cc221403(VS.95).aspx

+0

我認爲這是一個Windows應用程序?不是一個asp.net應用程序? – ram 2009-12-22 13:35:10

+0

對不起,這是一個wpf應用程序 – WtFudgE 2009-12-22 14:24:23

回答

7

既然你是在同一個線程中UI,進度條不刷新,其實整個窗口不刷新,因爲您的操作阻止主UI線程。

看看BackgroundWorker組件加載你的電影列表,它包含你需要的一切。

+0

我添加了MSDN文檔的鏈接。 – 2009-12-22 20:20:50

0

看來問題在於updateIMDBinfo調用正在捆綁您的UI線程。查看Thread或ThreadPool類的MSDN文檔以啓動該進程 - 然後用於更新進度條的調度可以在UI線程上暢通無阻。

我想現在正在發生的事情是您的進度條是空的,然後在完成時突然充滿。所有這些調度都在排隊等待控制從當前的消息處理器返回,但它並沒有返回,因爲它與實際工作相關聯。