8 (495) 215-53-16

info@notissimus.com

ул. Заозерная, 8

196084, Санкт-Петербург

09:00 - 20:00

сб.,вс. - выходные

Добавление большого списка объектов в ListBox на Windows Phone 8.0

 Блог    

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

Давайте рассмотрим эти варианты.

  1. Использование VirtualizingStackPanel. Позволяет отображать списки практически любой длины. Держит в памяти только объекты, которые в данный момент отображаются на экране. В минусы можно занести то, что если вам нужно выводить, например, по несколько объектов в ряд, то вам придётся в ручную их группировать. А так же то, что пользователь будет испытывать небольшой лаг при попытке быстро прокрутить список.
  2. Использовать асинхронное добавление элементов в ListBox. В плюсы можно отнести то, что прокрутка будет плавная и что вам не нужно в ручную группировать объекты и всё работает “из коробки”, а в минусы, что при отображение очень длинных списков приложение будет потреблять слишком много памяти и падать с OutOfMemoryException.

В этой статье я бы хотел рассмотреть второй вариант, так как в последнем приложении я использовал именно этот вариант ввиду не настолько больших списков объектов.

Посмотрим на код добавления элементов в список:

public ObservableCollection<ProductTile> Products;
 
// запускаем асинхронную задачу
DispatcherHelper.RunAsync(async () =>
{
    foreach (ProductModel product in products)
     {
         if (_shouldStop)
          {
             _isStopped = true;
            return;
          }
 
         ProductTile productTile = new ProductTile(product.ID, product.Name, …);
         Products.Add(productTile);
 
         // добавляем небольшую задержку, что бы элементы в списке появлялись постепенно,
         // но достаточно быстро
         await TaskEx.Delay(100); 
     }
}

 

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

 

При уходе со страницы отправляем сообщение на ViewModel страницы.

protected override void OnNavigatedFrom(NavigationEventArgs e)
{
     base.OnNavigatedFrom(e);
 
      Messenger.Default.Send(new StopUpdateProductsListPageMessage());
}

 

ViewModel принимает сообщение, что позволяет прекратить выполнение асинхронной задачи.

private static void OnStopUpdateProductsListPageMessage(StopUpdateProductsListPageMessage message)
{
      _shouldStop = true;
}

 

Данный способ довольно прост и не требует больших усилий для реализации. В следующей статье я постараюсь рассказать про использование VirtualizingStackPanel.

]]>