UWP: Новые возможности Visual State Manager (часть 2)

В предыдущем посте я рассказал о двух новых возможностях Visual State Manager’a: Setter’ах и адаптивных триггерах. Как вы увидели — адаптивные триггеры ограничивается только размером экрана, т.е. для других необходимых целей применить их не получится. Но в реальных приложениях вам может потребоваться  менять свой интерфейс на основе множества различных параметров, таких как Xbox контроллер, ориентация экрана, наличия данных и т.д. Таким образом, в этой статье я хочу показать, как продлить существующую инфраструктуру адаптивных триггеров, создав свой собственный.

Трудно найти приложение, которое не подключен к Интернету. Но получение данных из занимает некоторое время. Обычно я использую ProgressRing, что бы показать, что получение данных продолжается и я использую VisualStateManager, чтобы показать или скрыть элементы, основанные на имеющихся данных. Обычно есть три состояния: загрузка, загружено и ошибка. Естественно будет необходимо реализовать некоторый код, который изменит состояние приложения на основе состояния «модели представления». Давайте посмотрим, может ли мы вообще реализовывать свои собственные триггеры и поможет ли нам это в избежании создания лишнего кода.
Прежде всего, мы должны проверить, готов ли наш класс «вьюмодели» к использованию вместе с триггерами. Лучше всего реализовать свойство, которое показывает текущее состояние, а также событие, которое срабатывает каждый раз при изменении данного свойства. Конечно, лучше всего это реализовать в базовом классе.

public enum StateEnum
{
    Loading,
    Loaded,
    Error
}

public class StateChangeEventArgs:EventArgs
{
    public StateEnum State { get; set; }
}

public delegate void StateChangedDelegate(object model, StateChangeEventArgs args);

public class PageViewModel
{
    public event StateChangedDelegate StateChanged;

    public void InitModel()
    {
        if (StateChanged != null) StateChanged.Invoke(this, 
            new StateChangeEventArgs() { State = StateEnum.Loading });
        //load data
        if (StateChanged != null)
            StateChanged.Invoke(this,
                new StateChangeEventArgs() { State = StateEnum.Loaded });
    }
}

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

<Page.Resources>
    <st:PageViewModel x:Name="model"></st:PageViewModel>
</Page.Resources>

Самое время для создания собственного триггера. Для этого вы должны создать новый класс, который будет наследовать класс StateTriggerBase. Внутри класса можно объявить любые методы и свойства, но вы должны помнить, что вам будет необходимо вызывать метод SetActive. Благодаря ему можно активировать или деактивировать свой триггер. Например, я реализовал следующий класс:

public class DataTrigger: StateTriggerBase
{
    private PageViewModel model;

    public PageViewModel Model
    {
        get
        {
            return model;
        }
        set
        {
            model = value;
            model.StateChanged += Model_StateChanged;
        }
    }

    public string StateOfModel { get; set; }

    private void Model_StateChanged(object model, StateChangeEventArgs args)
    {
        SetActive(args.State.ToString().Equals(StateOfModel));
    }
}

Как вы можете видеть у меня есть два свойства, которые позволяют установить ссылку на текущую вьюмодель и определить состояние, которое мы будем использовать для активации триггера. После того, как вьюмодель инициализируется — мы активируем или деактивируем триггер с помощью обработчика события StateChanged.

В итоге у меня получились следующие состояния в XAML:

<VisualState x:Name="Loading">
    <VisualState.Setters>
        <Setter Target="gridView.Visibility" Value="Collapsed"></Setter>
        <Setter Target="progress.Visibility" Value="Visible"></Setter>
    </VisualState.Setters>
    <VisualState.StateTriggers>
        <st:DataTrigger Model="{StaticResource model}" 
           StateOfModel="Loading"></st:DataTrigger>
    </VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="Loaded">
    <VisualState.Setters>
        <Setter Target="gridView.Visibility" Value="Visible"></Setter>
        <Setter Target="progress.Visibility" Value="Collapsed"></Setter>
    </VisualState.Setters>
    <VisualState.StateTriggers>
        <st:DataTrigger Model="{StaticResource model}" 
           StateOfModel="Loaded"></st:DataTrigger>
    </VisualState.StateTriggers>
</VisualState>

Ссылка на источник: UWP: New features of Visual State Manager (part 2)

Реклама
Tagged with: , , , , ,
Опубликовано в Development, Windows 10
2 comments on “UWP: Новые возможности Visual State Manager (часть 2)
  1. Пишет «префикс пространства имён «st» не определён»

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

Connecting to %s

%d такие блоггеры, как: