2011-04-19 116 views
3

我有一些很好的動畫顯示淡入當我添加一個項目到我的列表框。我認爲在每個添加的項目之間稍微延遲一點可能會很酷,所以在添加所有項目時會有一個很好的層疊掃描(LB使用水平的StackPanel)。因爲我永遠不會有結果集> 10項,這對我來說似乎不算太糟糕。Silverlight - 每個項目之間的延遲添加到列表框

問題是,每次添加後列表框都不會添加項目,而是一直等到我的方法完成,然後全部顯示所有新項目。所以,對於下面的(誇大的)例子,我的頁面凍結了10秒,然後所有10個項目都顯示出來。

private void bookItemsLoaded(DownloadStringCompletedEventArgs e) { 
     BookResults.Clear(); 
     foreach (AmazonTitleSearchResultDTO item in BookItemDTOLoader.LoadObjects(e.Result)) { 
      BookResults.Add(new AmazonExplorerBookItemViewModel() { ImageURL = item.CoverURL, Title = item.Title, ASIN = item.ASIN }); 
      Thread.Sleep(1000); 
     } 
    } 

如何讓Silverlight每秒顯示一個項目? (是的,我知道這將是一個令人難以忍受的用戶體驗,真正的延遲將會小得多)

[這裏是link文章顯示如何做LB項目動畫,雖然大多數人讀這可能看到它已經]

編輯

答案下面是完美的,但這裏有一個稍微簡單的版本,SANS遞歸。

//get all the items to add into a local, tmeporary list, and call this method: 
private void AddBookToResults(List<AmazonTitleSearchResultDTO> bookList) 
{  
    DispatcherTimer Timer = new DispatcherTimer() { Interval = new TimeSpan(0, 0, 1) }; 
    int index = 0; 

    Timer.Tick += (s, e) => { 
     ItemCollection.Add(temp[index++]); 
     if (index == temp.Count) 
      Timer.Stop(); 
    }; 
    Timer.Start(); 
} 

回答

3

的問題是,您的整個計算過程已經在主線程的地方,直到你的方法完成,並給出了用戶界面繪製代碼有機會再次運行實際的UI動畫不會發生。這就是爲什麼所有動畫都會「同時」發生,即使您在添加每個動畫之後等待。如果你想避免這種情況,你需要將你的循環編程爲一系列委託在主線程上運行。

private void bookItemsLoaded(DownloadStringCompletedEventArgs e) { 
    BookResults.Clear(); 
    var bookList = BookItemDTOLoader.LoadObjects(e.Result).ToList(); 
    AddBookToResults(bookList, 0); 
} 

private void AddBookToResults(List<AmazonTitleSearchResultDTO> bookList, int index) 
{ 
    if (index == bookList.Count) { 
     return; 
    } 

    var item = bookList[index]; 
    BookResults.Add(new AmazonExplorerBookItemViewModel() { ImageURL = item.CoverURL, Title = item.Title, ASIN = item.ASIN }); 

    var timer = new DispatcherTimer(); 
    timer.Interval = new TimeSpan(0, 0, 1); 
    timer.Tick +=() => { 
     timer.Stop(); 
     AddBookToResults(bookList, index + 1); 
    }; 
    timer.Start(); 
} 

另一種解決方案是讓循環運行在後臺線程上。這比單線程代理版本更不可靠,但它代碼也更少,並且可能更易於理解。

+0

我希望我可以給這個超過+1並接受。這很好 - 我用較少的代碼編寫了一個類似的版本,我將其作爲編輯提出。 – 2011-04-19 14:36:29

+0

再次感謝 - 我仍然收回你投遞到那裏的遞歸 - 你是一個老LISP程序員偶然? :) – 2011-04-19 14:41:33

+1

@亞當,我從來沒有編程LISP,但即使沒有那個障礙,我從來沒有遇到過我不喜歡的遞歸。 – 2011-04-19 14:43:29