środa, 14 marca 2012

Windows 8 Metro na żywo, ale w Internecie - odc. 3

W dzisiejszym odcinku będzie coś dla leniwych -:) Na przykładzie dwóch funkcjonalności pokaże ile pracy pozwoli nam zaoszczędzić nowe API dla Windows 8.

Na ekranie startowym dodałem prezentowanie pobranych wcześniej plików video znajdujących się lokalnie na dysku. Miniatury i inne informacje są pobierane z samych plików. Dla dużej liczby z pewnością przydatna byłaby wirtualizacja. Chcemy też by w przypadku zmiany zawartości folderu podczas działania aplikacji (np. po zakończeniu pobierania danego pliku, gdy informacja o nim zniknie z listy pobrań) widok automatycznie się odświeżał.

mks2_2

mks2_3

Do zrealizowania tych wszystkich funkcjonalności wystarczył mi poniższy kod:

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            var folder = ApplicationData.Current.LocalFolder;           
            var queryOptions = new Windows.Storage.Search.QueryOptions();
            queryOptions.FolderDepth = Windows.Storage.Search.FolderDepth.Deep;
            queryOptions.IndexerOption = Windows.Storage.Search.IndexerOption.UseIndexerWhenAvailable;           

            var fileQuery = folder.CreateFileQueryWithOptions(queryOptions);

            var fif = new Windows.Storage.BulkAccess.FileInformationFactory(
                fileQuery,
                Windows.Storage.FileProperties.ThumbnailMode.PicturesView,
                283,
                Windows.Storage.FileProperties.ThumbnailOptions.UseCurrentScale,
                false
                );

            var dataSource = fif.GetVirtualizedFilesVector();
            itemGridView.ItemsSource = dataSource;
        }  

Kluczowa jest tutaj klasa FileInformationFactory, która jest data adapterem dla kontrolki ListView - w moim przypadku GridView (pochodna ListView). Jeśli chodzi o C# jest to nowość w wersji Consumer Preview (wcześniej data adaptery były dostępne tylko dla JavaScript, btw tam jest ich więcej). Widzimy też tutaj przykład odpytania systemu plików za pomocą tzw. file query, co jest bardzo popularne w Windows 8.  Podczas testów praktycznych zauważyłem, że Windows za folder lokalny aplikacji, uważał C:\Users\Marcin\AppData\Local\Packages\935cd7a4-a294-42de-9f2c-5b4a18c6ef67_79zxzkfye7zwc\LocalState.

Na koniec tego zagadnienia dygresja. Skoro następuje odświeżanie widoku przy operacjach dyskowych, to już w trakcie pobierania plików automatycznie pojawiały mi się pobierane elementy bez miniatur. Aby nowy elementy dodawały się dopiero po zakończeniu pobierania, pobierane pliki postanowiłem najpierw zapisywać w folderze na pliki tymczasowe aplikacji (ApplicationData.Current.TemporaryFolder), a następnie przenosić je do docelowego miejsca:

await resultFile.MoveAsync(ApplicationData.Current.LocalFolder); 

Po pobraniu pliku chcielibyśmy go sobie obejrzeć klikając w miniaturę. Do tego przydałby się odtwarzacz z przyciskami, suwakiem i regulacją głośności.

mks2_4

Możemy go sami zbudować w oparciu o kontrolkę MediaElement (podobnie jak w Silverlight i WPF), ale Windows 8 oferuje nam dodatkowo gotową kontrolkę MediaPlayer i to z niej tutaj skorzystamy:

      <MediaPlayer x:Name="player" Grid.RowSpan="2" AutomationProperties.Name="player" Loaded="player_Loaded"/>

Kontrolce tej ustawiam źródło w postaci strumienia z otwartego pliku (w moim przypadku nie jest to nawet sam StorageFile, tylko obiekt FileInformation przekazywany przez nawigację):

       private FileInformation _fi;       

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            _fi = e.Parameter as FileInformation;                    
        }       

        private async void player_Loaded(object sender, RoutedEventArgs e)
        {
            if (_fi != null)
            {
                var stream = await _fi.OpenAsync(FileAccessMode.Read);
                player.SetSource(stream, _fi.ContentType);
                player.Play();
            }  
        }

Brak komentarzy: