Поделиться через


Создание реакций на события Xamarin.Forms

Реакции на событие Xamarin.Forms создаются путем наследования от класса Behavior или Behavior<T>. В этой статье содержатся сведения о создании и использовании реакций на события Xamarin.Forms.

Обзор

Процесс создания реакции на событие Xamarin.Forms выглядит следующим образом:

  1. Создайте класс, наследующий от класса Behavior или Behavior<T>, где T — это тип элемента управления, к которому должна применяться реакция на событие.
  2. Переопределите метод OnAttachedTo для выполнения требуемой настройки.
  3. Переопределите метод OnDetachingFrom для выполнения требуемой очистки.
  4. Реализуйте основные функциональные возможности реакции на событие.

В результате вы получите структуру, приведенную в следующем примере кода:

public class CustomBehavior : Behavior<View>
{
    protected override void OnAttachedTo (View bindable)
    {
        base.OnAttachedTo (bindable);
        // Perform setup
    }

    protected override void OnDetachingFrom (View bindable)
    {
        base.OnDetachingFrom (bindable);
        // Perform clean up
    }

    // Behavior implementation
}

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

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

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

Создание реакции на событие Xamarin.Forms

В примере приложения демонстрируется реакция на событие NumericValidationBehavior, которая выделяет значение, введенное пользователем в элементе управления Entry, красным цветом, если оно не имеет тип double. Эта реакция на событие показана в следующем примере кода:

public class NumericValidationBehavior : Behavior<Entry>
{
    protected override void OnAttachedTo(Entry entry)
    {
        entry.TextChanged += OnEntryTextChanged;
        base.OnAttachedTo(entry);
    }

    protected override void OnDetachingFrom(Entry entry)
    {
        entry.TextChanged -= OnEntryTextChanged;
        base.OnDetachingFrom(entry);
    }

    void OnEntryTextChanged(object sender, TextChangedEventArgs args)
    {
        double result;
        bool isValid = double.TryParse (args.NewTextValue, out result);
        ((Entry)sender).TextColor = isValid ? Color.Default : Color.Red;
    }
}

NumericValidationBehavior является производным от класса Behavior<T>, где T — это Entry. Метод OnAttachedTo регистрирует обработчик событий для события TextChanged, при этом метод OnDetachingFrom отменяет регистрацию события TextChanged во избежание утечек памяти. Базовая функциональность реакции на событие обеспечивается методом OnEntryTextChanged, который анализирует значение, введенное пользователем в Entry, и присваивает свойству TextColor значение red (красный), если введенное значение не имеет тип double.

Примечание.

Xamarin.Forms не задает BindingContext для реакции на событие, так как реакции на событие можно использовать совместно и применять к нескольким элементам управления через стили.

Использование реакции на событие Xamarin.Forms

Каждый элемент управления Xamarin.Forms имеет коллекцию Behaviors, в которую можно добавить одну или несколько реакций на событие, как показано в следующем примере кода XAML:

<Entry Placeholder="Enter a System.Double">
    <Entry.Behaviors>
        <local:NumericValidationBehavior />
    </Entry.Behaviors>
</Entry>

В следующем примере кода показан эквивалентный элемент управления Entry на языке C#.

var entry = new Entry { Placeholder = "Enter a System.Double" };
entry.Behaviors.Add (new NumericValidationBehavior ());

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

Пример приложения с поведением Xamarin.Forms

Примечание.

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

Использование реакции на событие Xamarin.Forms с помощью стиля

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

  1. Добавьте присоединенное свойство в класс реакции на событие, который будет использоваться для управления добавлением или удалением реакции на событие, в элемент управления, к которому будет присоединена реакция на событие. Это присоединенное свойство должно регистрировать делегат propertyChanged, который будет выполняться при изменении значения свойства.
  2. Создайте методы получения и задания static для присоединенного свойства.
  3. Реализуйте логику в делегате propertyChanged для добавления и удаления реакции на событие.

В следующем примере кода показано присоединенное свойство, управляющее добавлением и удалением NumericValidationBehavior:

public class NumericValidationBehavior : Behavior<Entry>
{
    public static readonly BindableProperty AttachBehaviorProperty =
        BindableProperty.CreateAttached ("AttachBehavior", typeof(bool), typeof(NumericValidationBehavior), false, propertyChanged: OnAttachBehaviorChanged);

    public static bool GetAttachBehavior (BindableObject view)
    {
        return (bool)view.GetValue (AttachBehaviorProperty);
    }

    public static void SetAttachBehavior (BindableObject view, bool value)
    {
        view.SetValue (AttachBehaviorProperty, value);
    }

    static void OnAttachBehaviorChanged (BindableObject view, object oldValue, object newValue)
    {
        var entry = view as Entry;
        if (entry == null) {
            return;
        }

        bool attachBehavior = (bool)newValue;
        if (attachBehavior) {
            entry.Behaviors.Add (new NumericValidationBehavior ());
        } else {
            var toRemove = entry.Behaviors.FirstOrDefault (b => b is NumericValidationBehavior);
            if (toRemove != null) {
                entry.Behaviors.Remove (toRemove);
            }
        }
    }
    ...
}

Класс NumericValidationBehavior содержит присоединенное свойство AttachBehavior с методами задания и получения static, управляющее добавлением и удалением реакции на событие в элементе управления, к которому она будет присоединена. Это присоединенное свойство регистрирует метод OnAttachBehaviorChanged, который будет выполняться при изменении значения свойства. В зависимости от значения присоединенного свойства AttachBehavior, этот метод добавляет или удаляет реакцию на событие в элементе управления.

В следующем примере кода показан явный стиль для NumericValidationBehavior, который использует присоединенное свойство AttachBehavior и может применяться к элементам управления Entry:

<Style x:Key="NumericValidationStyle" TargetType="Entry">
    <Style.Setters>
        <Setter Property="local:NumericValidationBehavior.AttachBehavior" Value="true" />
    </Style.Setters>
</Style>

Чтобы применить Style к элементу управления Entry, для его свойства Style следует задать значение экземпляра Style с помощью расширения разметки StaticResource, как показано в следующем примере кода:

<Entry Placeholder="Enter a System.Double" Style="{StaticResource NumericValidationStyle}">

Дополнительные сведения о стилях см. в статье Стили .

Примечание.

Хотя вы можете добавить привязываемые свойства для реакции на событие, которая задается или запрашивается в XAML, в этом случае нужно создать реакции на событие с состоянием, которое не должно совместно использоваться между элементами управления в Style в ResourceDictionary.

Удаление реакции на событие из элемента управления

Метод OnDetachingFrom активируется при удалении реакции на событие из элемента управления и используется для выполнения любой требуемой очистки, например для отмены подписки на событие в целях предотвращения утечки памяти. Тем не менее реакции на событие не удаляются из элементов управления неявным образом, если коллекция Behaviors элемента управления изменяется с помощью метода Remove или Clear. В следующем примере кода показано удаление конкретной реакции на событие из коллекции Behaviors элемента управления:

var toRemove = entry.Behaviors.FirstOrDefault (b => b is NumericValidationBehavior);
if (toRemove != null) {
    entry.Behaviors.Remove (toRemove);
}

Кроме того, коллекцию Behaviors элемента управления можно очистить, как показано в следующем примере кода:

entry.Behaviors.Clear();

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

Итоги

В этой статье было показано создание и использование реакций на события Xamarin.Forms. Реакции на событие Xamarin.Forms создаются путем наследования от классов Behavior или Behavior<T>.