Pull to refresh

Добавление jump lists в приложение UWP

Reading time 5 min
Views 4K


Jump lists были и остаются частью классических приложений Windows, позволяя перейти к различному функционалу приложения. Например, открыть последний файл или запустить приложение с активированной фичей.
Приложения UWP позволяют нам использовать аналогичный функционал, реализуемый в виде дополнительных пунктов контекстного меню панели задач или плитки стартового экрана.

JumpList недоступны в ранних сборках 10-ки. Поэтому первым делом обновляем систему и SDK. Я обновился до 10.0.10586
Открываем App.xaml.cs и добавляем такой вот Task:

        public static async Task SetupJumpList()
        {
         JumpList jumpList = await JumpList.LoadCurrentAsync();
         jumpList.Items.Clear();

         JumpListItem photoItem = JumpListItem.CreateWithArguments("photo", "фото");
         photoItem.Logo = new Uri("ms-appx:///Assets/photo.png");
         JumpListItem videoItem = JumpListItem.CreateWithArguments("video", "видео");
         videoItem.Logo = new Uri("ms-appx:///Assets/video.png");

         jumpList.Items.Add(photoItem);
         jumpList.Items.Add(videoItem);

         await jumpList.SaveAsync();
        }

Добавляем необходимые пространства имен:

using System.Threading.Tasks;
using Windows.UI.StartScreen;

В свойствах проекта можно посмотреть минимальную версию целевой платформы. Если она довольно ранняя, то код внутри нашего Task-а необходимо будет обернуть в try-catch.
Взглянув на код, вы можете заметить, что он использует файлы photo.png и video.png из папки Assets. Эти файлы значков необходимо добавить в приложение.
Вызвать Task и зарегистрировать контекстное меню JumpList можно в любой момент. Давайте сделаем это в событии OnLaunched(LaunchActivatedEventArgs e).

await SetupJumpList();

В этом же событии OnLaunched можно определить было ли приложение открыто через пункт JumpList или же было открыто обычным способом. Аргумент LaunchActivatedEventArgs e содержит в себе необходимую информацию. Если его значением является «photo», то это значит, что приложение было открыто по контекстной ссылке «фото».
Вот такое меню у меня получилось:



Мне захотелось сделать так, чтобы при выборе пункта видео или фото переход происходил не на MainPage, а на какую-то другую страничку. Для этого первым делом создадим эту другую страничку. Я создал страницу с именем PhotoPage.xaml
Содержимое ее сделал довольно простым:

<Page
    x:Class="JumpListsDemo.PhotoPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:JumpListsDemo"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Image x:Name="imgPhoto" Width="auto" Height="auto"></Image>
        <TextBlock FontSize="28" HorizontalAlignment="Center">Страничка с фото</TextBlock>
    </Grid>
</Page>

Отловим каким образом было открыто приложение и сделаем переход на страничку PhotoPage. Для этого, в App.xaml.cs нужно найти внутри метода OnLaunched код:

rootFrame.Navigate(typeof(MainPage), e.Arguments);

и заменить его на что-то вроде:

      if (e.Arguments == "photo")
   {
      rootFrame.Navigate(typeof(PhotoPage), e.Arguments);
   }
      else
   {
      rootFrame.Navigate(typeof(MainPage), e.Arguments);
   }

Вуаля. При выборе через контекстное меню пункта «фото» нам будет открываться страничка с видео. Сделать переход по пункту «видео» можно через else if, либо заменив всю конструкцию на switch.

Коротенькая статья получилась, правда? Давайте бонусом вкратце рассмотрим, как можно запомнить последний открытый файл и добавить ссылку на него в JumpList.
Допустим где-то в программе мы открываем файл с помощью FileOpenPicker.

  FileOpenPicker filePicker = new FileOpenPicker();
  filePicker.FileTypeFilter.Add(".jpg");
  filePicker.ViewMode = PickerViewMode.List;
  filePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
  filePicker.SettingsIdentifier = "picker1";
  Windows.Storage.StorageFile f = await filePicker.PickSingleFileAsync();

Теперь в случае если файл был выбран мы сделаем с ним что хотели, и после запишем его в список последних посещенных файлов:

            if (f != null)
            {
             // делаем что нам нужно и….. 
            // записываем файл в последние использованные
            String mruToken = MostRecentlyUsedList.Add(f, f.Name);
            }

В UWP точно так же как и в приложениях Windows 8.x особые правила доступа к файлам. Если в манифесте прописаны разрешения, то может быть получен доступ к папкам/библиотекам изображений, музыки, видео. Для того чтобы получить доступ к другим файлам необходимо чтобы пользователь выбрал их с помощью File- или Folder- Picker-a. Ну и чтобы после перезапуска приложения разрешение доступа к содержимому файла не терялось, нужно использовать свойство MostRecentlyUsedList класса Windows.Storage.AccessCache.StorageApplicationPermissions. А значит в код должно быть добавлено пространство имен:

using Windows.Storage.AccessCache.StorageApplicationPermissions;

Немного изменим наш первый пример. Перенесем регистрацию на экране блокировки из OnLaunched в код который открывает файл. В конец if только что упомянутого кода добавим

await App.SetupJumpList(f);

Кстати, SetupJumpList тоже изменим:

public static async Task SetupJumpList(Windows.Storage.StorageFile fl)
        {
                JumpList jumpList = await JumpList.LoadCurrentAsync();
                jumpList.Items.Clear();
                JumpListItem lastItem = JumpListItem.CreateWithArguments("lastfile", fl.DisplayName);
                lastItem.Logo = new Uri("ms-appx:///Assets/photo.png");
                jumpList.Items.Add(lastItem);
                await jumpList.SaveAsync();
        }

Внесем изменения в OnLaunched

      if (e.Arguments == "lastfile")
   {
      rootFrame.Navigate(typeof(PhotoPage), e.Arguments);
   }
      else
   {
      rootFrame.Navigate(typeof(MainPage), e.Arguments);
   }

Теперь осталось только при навигации на страницу PhotoPage обработать аргумент, который передается в качестве параметра вызовом

      rootFrame.Navigate(typeof(PhotoPage), e.Arguments);

Этот аргумент как видно передается из App.xaml.cs в страницу PhotoPage. Отловить его можно в событии OnNavigatedTo. Код который необходимо добавить в PhotoPage такой:

        protected  override async void OnNavigatedTo(NavigationEventArgs e)
        {
            try
            {
                Windows.Storage.StorageFile f;
                String mruFirstToken = MostRecentlyUsedList.Entries.FirstOrDefault().Token;
                f = await MostRecentlyUsedList.GetFileAsync(mruFirstToken);
                SetPhoto(f);
            }catch{}
        }

        public async void SetPhoto(StorageFile storageFile)
        {
            BitmapImage image = new BitmapImage();
            IRandomAccessStream stream = await storageFile.OpenAsync(FileAccessMode.Read);
            image.SetSource(stream);
            imgPhoto.Source = image;
        }

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



Написано по мотивам:
Developing for Windows 10 – Implementing jump lists
UWP Quick tip – JumpLists
Tags:
Hubs:
+8
Comments 2
Comments Comments 2

Articles