Silverlight - 向listbox添加每个项之间的延迟时间

3
我有一些漂亮的动画,当我向列表框中添加项目时会显示淡入效果。我认为在每个添加的项目之间放置一个轻微的延迟可能很酷,这样就可以在所有项目被添加时产生一个漂亮的级联效果(LB使用水平StackPanel)。由于我永远不会有一个结果集> 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项目动画的文章链接,尽管大多数阅读本文的人可能已经看过了]
编辑
下面的答案很完美,但这里有一个稍微简单一点的版本,没有递归。
//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();
}
1个回答

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();
}

另一种解决方案是在后台线程上运行循环。这比单线程委托版本不太可靠,但代码更少,可能更易于理解。


我希望我能给予更多的赞和接受。这很好 - 我写了一个类似的版本,代码更少,我会作为编辑发布。 - Adam Rackis
再次感谢 - 我仍然被你加入的递归所震撼 - 你是一位老LISP程序员吗? :) - Adam Rackis
1
@Adam,我从来没有编写过LISP程序,但即使没有这个障碍,我也从来没有遇到过我不喜欢的递归。 - JSBձոգչ
@Adam,附言:我非常喜欢你的修改——它比我的更清晰、更高效。干得好! - JSBձոգչ
谢谢您先生。感谢您帮助我理解问题。如果这不是一个如此晦涩的问题,您可能会得到更多的赞 :) - Adam Rackis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接