Silverlight - задержка между каждым элементом, добавляемым в список - PullRequest
3 голосов
/ 19 апреля 2011

У меня есть несколько хороших анимаций, которые показывают появление, когда я добавляю элемент в список.Я подумал, что было бы неплохо поместить небольшую задержку между каждым добавляемым элементом, так что будет хороший проход по каскаду (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 голосов
/ 19 апреля 2011

Проблема в том, что весь ваш расчет выполняется в главном потоке, а фактическая анимация пользовательского интерфейса не происходит до тех пор, пока ваш метод не завершит работу и не предоставит возможность отрисовки кода пользовательского интерфейса снова. Вот почему все анимации происходят "сразу", даже если вы ожидали добавления каждой из них. Если вы хотите избежать этого, вам нужно запрограммировать свой цикл как серию делегатов для запуска в главном потоке.

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

Альтернативное решение - запустить цикл в фоновом потоке. Это менее надежно, чем однопотоковая версия делегата, но также меньше кода и может быть легче для понимания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...