当我将一个项目添加到我的列表框时,我有一些很好的动画显示淡入。我认为在每个添加的项目之间稍微延迟可能会很酷,因此在添加所有项目时会有一个很好的级联扫描(LB使用水平StackPanel)。因为我永远不会有结果集>这10件事对我来说似乎并不太糟糕。
问题是,列表框不会在每次添加后添加项目,而是等到我的方法完成后再显示所有新项目。因此,对于下面的(夸大)示例,我的页面会冻结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每秒显示一个项目? (是的,我知道这将是一种令人难以忍受的用户体验。真正的延迟会小很多)
[以下是显示如何进行LB项目动画的文章的link,尽管大多数阅读此内容的人可能已经看过它了
修改
下面的答案是完美的,但这是一个稍微简单的版本,没有递归。
//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();
}
答案 0 :(得分:3)
问题是您的整个计算都是在主线程上进行的,并且在您的方法完成之前,实际的UI动画不会发生,并且会为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();
}
另一种解决方案是让循环在后台线程上运行。这不如单线程委托版本可靠,但代码也少,而且可能更容易理解。