2011-04-19 81 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