Необходимо заполнить список следующей страницы, выполнив код на предыдущей странице.

Я работаю над приложением музыкального проигрывателя Windows Phone 8.1 на С#/XAML.

Когда пользователь нажмет кнопку «Далее» на вводной странице и перейдет на вторую страницу, он увидит список. Этот список должен быть заполнен всеми песнями на телефоне. Но это, кажется, занимает не менее 3-5 секунд, и в конечном итоге пользователю приходится смотреть на пустой белый экран, пока все песни не будут загружены в список, а затем список помещается в список.

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

Если я остаюсь на первой странице в течение 3-5 секунд, а затем перехожу на следующую страницу, я вижу список, заполненный всеми песнями в порядке. Но вместо этого, если, как только приложение откроется, я сразу же нажму кнопку и перейду на следующую страницу, тогда я увижу список только наполовину заполненным. Хотя список в конечном итоге может собрать все песни, он заполняет список только до той точки, в которой он был, когда он читал все песни.

MainPage.xaml.cs (первая страница):

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Storage;
using Windows.Storage.FileProperties;
using Windows.UI;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

namespace Beta
{
    public sealed partial class MainPage : Page
    {
        List<Music> source = new List<Music>();
        public MainPage()
        {
            this.InitializeComponent();
            this.setAllItems();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Frame.Navigate(typeof(Player));
        }

        private async Task getMusic(IStorageFolder folder)
        {
            var folders = await folder.GetFoldersAsync();
            if (folders != null)
                foreach (var fol in folders)
                    await getMusic(fol);

            var files = await folder.GetFilesAsync();
            foreach (var file in files)
            {
                MusicProperties musicProperties = await file.Properties.GetMusicPropertiesAsync();
                this.source.Add(new Music(musicProperties.Artist, musicProperties.Title, musicProperties.Album));
                Player.source = this.source;
            }
        }
        private async void setAllItems()
        {
            await this.getMusic(Windows.Storage.KnownFolders.MusicLibrary);
        }
    }
}

Player.xaml.cs (вторая страница):

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Beta;
using Windows.Storage;
using System.Threading.Tasks;
using Windows.Storage.Search;
using Windows.Storage.FileProperties;
using System.Diagnostics;

namespace Beta
{
    public sealed partial class Player : Page
    {
        public static List<Music> source;
        public Player()
        {
            this.InitializeComponent();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            this.contentList.ItemsSource = source;
            contentList.UpdateLayout();
        }
    }
}

Когда я попадаю на страницу проигрывателя (вторую), я подождал минуту, а затем нажал кнопку (не показана), которая использовала бы Debug.WriteLine() для печати всего содержимого списка. Он распечатал полный список.

Таким образом, асинхронная задача выполняет свою работу и заполняет список, но не может правильно завершить просмотр списка.

У меня есть 2 вопроса:

  1. Как заставить представление списка самозаполняться большим количеством записей по мере того, как список получает больше элементов (возможно, в режиме реального времени, когда оставшиеся элементы из списка постоянно добавляются в список, пока список не будет завершен?

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


person DemCodeLines    schedule 23.08.2014    source источник
comment
Для вашего первого вопроса: вместо этого используйте наблюдаемую коллекцию: back-wp8/25398330#25398330" title="как уведомить пользовательский интерфейс о том, что его свойство изменилось по сравнению с кодом позади wp8"> stackoverflow.com/questions/25397664/   -  person Chubosaurus Software    schedule 23.08.2014
comment
Что касается вашего второго вопроса, нам нужно сначала найти замедление. Насколько быстр этот рекурсивный вызов? Это что основное замедление?   -  person Chubosaurus Software    schedule 23.08.2014
comment
@ChubosaurusSoftware Может быть. Как еще я мог узнать?   -  person DemCodeLines    schedule 23.08.2014
comment
Вы можете использовать какой-либо тип профилировщика, но если у вас нет хорошего, просто используйте Date.Now() до и после события, а затем возьмите разницу.   -  person Chubosaurus Software    schedule 24.08.2014
comment
Если обход каталогов и файлов является основной причиной, по которой вы видите эту огромную задержку, я бы запустил ее в другом потоке. Если вы сделаете это таким образом, вам нужно будет Dispatch Invoke добавить в свой ListView.   -  person Chubosaurus Software    schedule 24.08.2014