Xamarin.Forms Привязываемые свойства
Привязываемые свойства расширяют функциональные возможности свойств CLR путем резервного копирования свойства с типом BindableProperty
, а не резервного копирования свойства с полем. Цель привязываемых свойств — предоставить систему свойств, которая поддерживает привязку данных, стили, шаблоны и значения, заданные через отношения родительского-дочернего объекта. Кроме того, привязываемые свойства могут предоставлять значения по умолчанию, проверку значений свойств и обратные вызовы, отслеживающие изменения свойств.
Свойства должны быть реализованы как привязываемые свойства для поддержки одной или нескольких следующих функций:
- Действует как допустимое целевое свойство для привязки данных.
- Задание свойства с помощью стиля.
- Предоставление значения свойства по умолчанию, отличное от значения по умолчанию для типа свойства.
- Проверка значения свойства.
- Мониторинг изменений свойств.
Примеры привязываемых Xamarin.Forms свойств: Label.Text
, Button.BorderRadius
и StackLayout.Orientation
. Каждое привязываемое свойство имеет соответствующее public static readonly
поле типа BindableProperty
, которое предоставляется в одном классе и является идентификатором привязываемого свойства. Например, соответствующий Label.TextProperty
идентификатор привязываемого свойства для Label.Text
свойства.
Создание привязываемого свойства
Процесс создания привязываемого свойства выглядит следующим образом:
BindableProperty
Создайте экземпляр с одной изBindableProperty.Create
перегрузок метода.- Определите методы доступа к свойствам для экземпляра
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
собственной платформе.