Контракт Settings в WinRT (Windows 8)

в 14:50, , рубрики: .net, windows, Windows 8, WinRT, контракты, метки: , ,

Одним из основных контрактов доступных в чудо-панели Windows 8 является контракт Settings.
Активация панели настроек осуществляется соответствующей кнопкой «Settings» в чудо панели:
image

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

В этой статье мы рассмотрим две темы:.
Добавление поддержки контракта Settings
Добавление собственной панели настроек.


Добавление поддержки контракта Settings
Пример интеграции настроек есть в официальных примерах:
App settings sample

Рассмотрим как максимально просто реализовать поддержку контракта.
На странице в методе OnNavigateTo и OnNavigateFrom мы подпишемся на событие запроса настроек и отпишемся от события при уходе со страницы:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    SettingsPane.GetForCurrentView().CommandsRequested += Settings_CommandsRequested;
}
 
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
    SettingsPane.GetForCurrentView().CommandsRequested -= Settings_CommandsRequested;
}

SettingsPane находится в пространстве имен Windows.UI.ApplicationSettings, соответственно в заголовке страницы должно быть соответствующее объявление пространства имен:

using Windows.UI.ApplicationSettings;

Событие CommandsRequested срабатывает в тот момент, когда пользователь в чудо панели активирует панель настроек. Мы должны вернуть тот список команд, которые захотим предоставить пользователю. К примеру, добавим две команды About и Say Hello!.. Первая будет перенаправлять на страницу About а вторая команда будет показывать диалоговое окно.

void Settings_CommandsRequested(SettingsPane sender, SettingsPaneCommandsRequestedEventArgs args)
{
    var viewAboutPage = new SettingsCommand("", "About", cmd =>
    {
        (Window.Current.Content as Frame).Navigate(typeof (AboutPage));
    });
    args.Request.ApplicationCommands.Add(viewAboutPage);
 
    var sayHelloCommand = new SettingsCommand("", "Say Hello!", cmd =>
    {
        new MessageDialog("Hello! World!").ShowAsync();
    });
    args.Request.ApplicationCommands.Add(sayHelloCommand);
}

Если мы все сделали правильно, то мы должны увидеть следующую панель с нашими командами:

image

При этому пункт Permissions доступна всегда и пользователь всегда может зайти туда и управлять настройками безопасности.

Добавление собственной панели настроек

Зачастую нам нужно гораздо больше чем одна кнопка.

Возможно в нашей панели у нас будут использоваться ToggleSwitch, Slider, Combobox или другие элементы управления.

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

Пример такой панели можно увидеть практически в каждом приложении по команде «Permissions»:

image

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

В частности я воспользовался решением описанным здесь. Несмотря на то что реализация отличается основная идея решения взята оттуда.

В первую очередь мы должны добавить UserControl (UC) который будет содержать в себе все необходимые настройки, назовем его AppSettingsPanel

В UC реализуем следующий код:

<UserControl
   ....
   Width="350">
    <Grid Background="DarkGreen" Margin="0">
        <Grid Margin="0" Height="78" VerticalAlignment="Top" Background="Green">
            <Button HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Style="{StaticResource PreviousAppBarButtonStyle}" Click="ButtonGoBack_Click"/>    
        </Grid>
        <ToggleSwitch Header="Enable details view" Margin="10,83,0,0" VerticalAlignment="Top" />
    </Grid>
</UserControl>

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

В обработчике напишем следующий код для кнопки «назад»:

private void ButtonGoBack_Click(object sender, RoutedEventArgs e)
 {
     if (this.Parent is Popup)
     {
         (this.Parent as Popup).IsOpen = false;
     }
     SettingsPane.Show();
 }

Теперь когда пользователь нажмет «назад» будет скрыта текущая панель и снова откроется панель Settings

Далее мы добавим в наш проект небольшой воспомгательный класс:

    public class CustomPanelCommand
    {
        private readonly SettingsCommand command;
 
        public CustomPanelCommand(UserControl parentPage, string label, Type typeOfPanel)
        {
            command = new SettingsCommand("", label, (cmd) =>
            {
                customSettingsPopup = new Popup()
                {
                    IsLightDismissEnabled = true,
                    Height = parentPage.ActualHeight
                };
                customSettingsPopup.Closed += customSettingsPopup_Closed;
                Window.Current.Activated += Current_Activated;
 
                var panel = Activator.CreateInstance(typeOfPanel) as UserControl;
                panel.UpdateLayout();
                customSettingsPopup.Width = panel.Width;
                customSettingsPopup.Height = panel.Height = parentPage.ActualHeight;
 
 
                customSettingsPopup.Child = panel;
                customSettingsPopup.SetValue(Canvas.LeftProperty, parentPage.ActualWidth - customSettingsPopup.Width);
                customSettingsPopup.IsOpen = true;
            });
        }
 
        public SettingsCommand GetCommand()
        {
            return command;
        }
 
        private Popup customSettingsPopup;
        void customSettingsPopup_Closed(object sender, object e)
        {
            Window.Current.Activated -= Current_Activated;
        }
 
        void Current_Activated(object sender, Windows.UI.Core.WindowActivatedEventArgs e)
        {
            if (e.WindowActivationState == Windows.UI.Core.CoreWindowActivationState.Deactivated)
            {
                customSettingsPopup.IsOpen = false;
            }
        }
    }

Теперь с помощью этого вспомогательного класса мы можем добавить несколько кнопок с кастомной панелью или же отдельные панели настроек для каждой страницы.

Используя этот вспомгательный класс добавим на нашей странице код для отображение нашей панели по кнопке «my custom settings»

void Settings_CommandsRequested(SettingsPane sender, SettingsPaneCommandsRequestedEventArgs args)
{
    var customCommand =new CustomPanelCommand(this, "My custom settings", typeof (AppSettingsPanel)).GetCommand();
    args.Request.ApplicationCommands.Add(customCommand);
 
}

Теперь, если мы активируем настройки и выберем пункт «My custom settings» то должны увидеть следующую панель:

image

Исходный код к статье можно скачать здесь

Автор: Atreides07

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js