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


Xamarin.Forms Привязываемые свойства

Привязываемые свойства расширяют функциональные возможности свойств CLR путем резервного копирования свойства с типом BindableProperty , а не резервного копирования свойства с полем. Цель привязываемых свойств — предоставить систему свойств, которая поддерживает привязку данных, стили, шаблоны и значения, заданные через отношения родительского-дочернего объекта. Кроме того, привязываемые свойства могут предоставлять значения по умолчанию, проверку значений свойств и обратные вызовы, отслеживающие изменения свойств.

Свойства должны быть реализованы как привязываемые свойства для поддержки одной или нескольких следующих функций:

  • Действует как допустимое целевое свойство для привязки данных.
  • Задание свойства с помощью стиля.
  • Предоставление значения свойства по умолчанию, отличное от значения по умолчанию для типа свойства.
  • Проверка значения свойства.
  • Мониторинг изменений свойств.

Примеры привязываемых Xamarin.Forms свойств: Label.Text, Button.BorderRadiusи StackLayout.Orientation. Каждое привязываемое свойство имеет соответствующее public static readonly поле типа BindableProperty , которое предоставляется в одном классе и является идентификатором привязываемого свойства. Например, соответствующий Label.TextPropertyидентификатор привязываемого свойства для Label.Text свойства.

Создание привязываемого свойства

Процесс создания привязываемого свойства выглядит следующим образом:

  1. BindableProperty Создайте экземпляр с одной из BindableProperty.Create перегрузок метода.
  2. Определите методы доступа к свойствам для экземпляра BindableProperty .

Все BindableProperty экземпляры должны быть созданы в потоке пользовательского интерфейса. Это означает, что только код, который выполняется в потоке пользовательского интерфейса, может получить или задать значение привязываемого свойства. BindableProperty Однако доступ к экземплярам можно получить из других потоков путем маршалинга в поток пользовательского Device.BeginInvokeOnMainThread интерфейса с помощью метода.

Создание свойства

Чтобы создать BindableProperty экземпляр, содержащий класс должен быть производным от BindableObject класса. BindableObject Однако класс имеет высокий уровень в иерархии классов, поэтому большинство классов, используемых для функций пользовательского интерфейса, поддерживают привязываемые свойства.

Привязываемое свойство можно создать путем объявления public static readonly свойства типа BindableProperty. Привязываемое свойство должно быть задано возвращаемым значением одной из BindableProperty.Create перегрузок метода. Объявление должно находиться в теле производного класса, но вне определений BindableObject элементов.

Как минимум, при создании BindablePropertyидентификатора необходимо указать вместе со следующими параметрами:

  • Имя BindableProperty.
  • Тип свойства.
  • Тип объекта владения.
  • Значение по умолчанию для свойства. Это гарантирует, что свойство всегда возвращает определенное значение по умолчанию, если оно не задано, и оно может отличаться от значения по умолчанию для типа свойства. Значение по умолчанию будет восстановлено при ClearValue вызове метода в привязываемом свойстве.

Внимание

Соглашение об именовании для привязываемых свойств заключается в том, что идентификатор привязываемого свойства должен соответствовать имени свойства, указанному в методе Create , с добавлением свойства к нему.

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

public static readonly BindableProperty EventNameProperty =
  BindableProperty.Create ("EventName", typeof(string), typeof(EventToCommandBehavior), null);

При этом создается BindableProperty экземпляр с именем EventNameProperty, типом string. Свойство принадлежит классу EventToCommandBehavior и имеет значение nullпо умолчанию.

При необходимости при создании экземпляра BindableProperty можно указать следующие параметры:

  • Режим привязки. Используется для указания направления, в котором будут распространяться изменения значения свойства. В режиме привязки по умолчанию изменения будут распространяться из источника на целевой объект.
  • Делегат проверки, который будет вызываться при установке значения свойства. Дополнительные сведения см. в статье Обратные вызовы проверки.
  • Измененный делегат свойства, который будет вызываться при изменении значения свойства. Дополнительные сведения см. в разделе "Обнаружение изменений свойств".
  • Делегат изменения свойства, который будет вызываться при изменении значения свойства. Этот делегат имеет ту же подпись, что и измененный делегат свойства.
  • Делегат принудительного значения, который будет вызываться при изменении значения свойства. Дополнительные сведения см. в разделе обратных вызовов значения Coerce.
  • Значение Func свойства по умолчанию используется для инициализации значения свойства по умолчанию. Дополнительные сведения см. в разделе "Создание значения по умолчанию" с помощью Func.

Создание методов доступа

Методы доступа к свойствам необходимы для использования синтаксиса свойств для доступа к привязываемому свойству. Метод Get доступа должен возвращать значение, содержащееся в соответствующем привязываемом свойстве. Это можно сделать путем вызова GetValue метода, передачи идентификатора привязываемого свойства, для которого требуется получить значение, а затем приведения результата к требуемому типу. Метод Set доступа должен задать значение соответствующего привязываемого свойства. Это можно добиться, вызвав SetValue метод, передав идентификатор привязываемого свойства, для которого необходимо задать значение, и значение, которое необходимо задать.

В следующем примере кода показаны методы доступа для привязываемого EventName свойства:

public string EventName
{
  get { return (string)GetValue (EventNameProperty); }
  set { SetValue (EventNameProperty, value); }
}

Использование привязываемого свойства

После создания привязываемого свойства его можно использовать из XAML или кода. В XAML это достигается путем объявления пространства имен с префиксом, с объявлением пространства имен, указывающим имя пространства имен CLR и необязательное имя сборки. Дополнительные сведения см. в разделе "Пространства имен XAML".

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

<ContentPage ... xmlns:local="clr-namespace:EventToCommandBehavior" ...>
  ...
</ContentPage>

Объявление пространства имен используется при задании привязываемого EventName свойства, как показано в следующем примере кода XAML:

<ListView ...>
  <ListView.Behaviors>
    <local:EventToCommandBehavior EventName="ItemSelected" ... />
  </ListView.Behaviors>
</ListView>

Эквивалентный код на языке C# показан в следующем примере:

var listView = new ListView ();
listView.Behaviors.Add (new EventToCommandBehavior
{
  EventName = "ItemSelected",
  ...
});

Расширенные сценарии

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

Обнаружение изменений свойств

Метод static обратного вызова с измененным свойством можно зарегистрировать с привязываемым свойством, указав propertyChanged параметр для BindableProperty.Create метода. Указанный метод обратного вызова будет вызываться при изменении значения привязываемого свойства.

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

public static readonly BindableProperty EventNameProperty =
  BindableProperty.Create (
    "EventName", typeof(string), typeof(EventToCommandBehavior), null, propertyChanged: OnEventNameChanged);
...

static void OnEventNameChanged (BindableObject bindable, object oldValue, object newValue)
{
  // Property changed implementation goes here
}

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

Обратные вызовы проверки

Метод static обратного вызова проверки можно зарегистрировать с привязываемым свойством, указав validateValue параметр для BindableProperty.Create метода. Указанный метод обратного вызова будет вызываться при установке значения привязываемого свойства.

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

public static readonly BindableProperty AngleProperty =
  BindableProperty.Create ("Angle", typeof(double), typeof(HomePage), 0.0, validateValue: IsValidValue);
...

static bool IsValidValue (BindableObject view, object value)
{
  double result;
  bool isDouble = double.TryParse (value.ToString (), out result);
  return (result >= 0 && result <= 360);
}

Обратные вызовы проверки предоставляются со значением и должны возвращаться true , если значение допустимо для свойства, в противном случае false. Исключение будет возникать, если возвращается falseобратный вызов проверки, который должен обрабатываться разработчиком. Обычное использование метода обратного вызова проверки ограничивает значения целых чисел или двойных значений при установке привязываемого свойства. Например, метод проверяет, IsValidValue является double ли значение свойства в диапазоне от 0 до 360.

Обратные вызовы со значением coerce

Метод static обратного вызова принудительного значения можно зарегистрировать с привязываемым свойством, указав coerceValue параметр для BindableProperty.Create метода. Указанный метод обратного вызова будет вызываться при изменении значения привязываемого свойства.

Внимание

Тип BindableObject имеет CoerceValue метод, который можно вызвать для принудительной переоценки значения его BindableProperty аргумента, вызывая обратный вызов значения принудительная.

Обратные вызовы значения coerce используются для принудительного повторного определения привязываемого свойства при изменении значения свойства. Например, обратный вызов принудительного значения можно использовать, чтобы убедиться, что значение одного привязываемого свойства не превышает значение другого привязываемого свойства.

В следующем примере кода показано, как Angle привязываемое свойство регистрирует CoerceAngle метод в качестве метода обратного вызова со значением coerce:

public static readonly BindableProperty AngleProperty = BindableProperty.Create (
  "Angle", typeof(double), typeof(HomePage), 0.0, coerceValue: CoerceAngle);
public static readonly BindableProperty MaximumAngleProperty = BindableProperty.Create (
  "MaximumAngle", typeof(double), typeof(HomePage), 360.0, propertyChanged: ForceCoerceValue);
...

static object CoerceAngle (BindableObject bindable, object value)
{
  var homePage = bindable as HomePage;
  double input = (double)value;

  if (input > homePage.MaximumAngle)
  {
    input = homePage.MaximumAngle;
  }
  return input;
}

static void ForceCoerceValue(BindableObject bindable, object oldValue, object newValue)
{
  bindable.CoerceValue(AngleProperty);
}

Метод CoerceAngle проверяет значение MaximumAngle свойства, а если Angle значение свойства больше, чем оно, оно принудивает значение к значению MaximumAngle свойства. Кроме того, при MaximumAngle изменении свойства обратный вызов значения coerce вызывается для Angle свойства путем вызова CoerceValue метода.

Создание значения по умолчанию с помощью Func

Можно Func использовать для инициализации значения по умолчанию привязываемого свойства, как показано в следующем примере кода:

public static readonly BindableProperty SizeProperty =
  BindableProperty.Create ("Size", typeof(double), typeof(HomePage), 0.0,
  defaultValueCreator: bindable => Device.GetNamedSize (NamedSize.Large, (Label)bindable));

Для defaultValueCreator параметра задано Func Device.GetNamedSize значение, вызывающее метод для возврата double именованного размера шрифта, используемого на Label собственной платформе.