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

Загрузить образец загрузить примерDownload Sample Download the sample

Привязываемые свойства расширяют функциональные возможности свойства CLR путем резервного копирования свойства с BindableProperty типом, а не для резервного копирования свойства с полем.Bindable properties extend CLR property functionality by backing a property with a BindableProperty type, instead of backing a property with a field. Назначение свойств, допускающих привязку, заключается в предоставлении системы свойств, поддерживающей привязку данных, стили, шаблоны и значения, заданные с помощью связей типа «родители-потомки».The purpose of bindable properties is to provide a property system that supports data binding, styles, templates, and values set through parent-child relationships. Кроме того, привязываемые свойства могут предоставлять значения по умолчанию, проверку значений свойств и обратные вызовы, которые отслеживают изменения свойств.In addition, bindable properties can provide default values, validation of property values, and callbacks that monitor property changes.

Свойства должны быть реализованы в виде связываемых свойств для поддержки одной или нескольких из следующих функций:Properties should be implemented as bindable properties to support one or more of the following features:

  • Действует как допустимое целевое свойство для привязки данных.Acting as a valid target property for data binding.
  • Задание свойства с помощью стиля.Setting the property through a style.
  • Предоставление значения свойства по умолчанию, отличного от используемого по умолчанию для типа свойства.Providing a default property value that's different from the default for the type of the property.
  • Проверка значения свойства.Validating the value of the property.
  • Наблюдение за изменениями свойств.Monitoring property changes.

Примеры Xamarin.Forms связываемых свойств включают Label.Text , Button.BorderRadius и StackLayout.Orientation .Examples of Xamarin.Forms bindable properties include Label.Text, Button.BorderRadius, and StackLayout.Orientation. Каждое связываемое свойство имеет соответствующее public static readonly поле типа, которое BindableProperty представлено в том же классе и является идентификатором привязываемого свойства.Each bindable property has a corresponding public static readonly field of type BindableProperty that is exposed on the same class and that is the identifier of the bindable property. Например, соответствующий идентификатор свойства привязки для Label.Text свойства — Label.TextProperty .For example, the corresponding bindable property identifier for the Label.Text property is Label.TextProperty.

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

Процесс создания привязываемого свойства выглядит следующим образом:The process for creating a bindable property is as follows:

  1. Создайте BindableProperty экземпляр с одной из BindableProperty.Create перегрузок метода.Create a BindableProperty instance with one of the BindableProperty.Create method overloads.
  2. Определите методы доступа к свойствам для BindableProperty экземпляра.Define property accessors for the BindableProperty instance.

Все BindableProperty экземпляры должны быть созданы в потоке пользовательского интерфейса.All BindableProperty instances must be created on the UI thread. Это означает, что только код, выполняемый в потоке пользовательского интерфейса, может получить или задать значение привязываемого свойства.This means that only code that runs on the UI thread can get or set the value of a bindable property. Однако BindableProperty доступ к экземплярам можно осуществлять из других потоков путем маршалирования в поток пользовательского интерфейса с помощью Device.BeginInvokeOnMainThread метода.However, BindableProperty instances can be accessed from other threads by marshaling to the UI thread with the Device.BeginInvokeOnMainThread method.

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

Чтобы создать BindableProperty экземпляр, содержащий класс должен быть производным от BindableObject класса.To create a BindableProperty instance, the containing class must derive from the BindableObject class. Однако BindableObject класс имеет высокий уровень в иерархии классов, поэтому большинство классов, используемых для функциональности пользовательского интерфейса, поддерживают связываемые свойства.However, the BindableObject class is high in the class hierarchy, so the majority of classes used for user interface functionality support bindable properties.

Свойство, доступное для привязки, может быть создано путем объявления public static readonly свойства типа BindableProperty .A bindable property can be created by declaring a public static readonly property of type BindableProperty. Свойству BIND должно быть присвоено возвращаемое значение одного из [ BindableProperty.Create ] (xref: Xamarin.Forms . Биндаблепроперти. Create (System. String, System. Type, System. Type, System. Object, Xamarin.Forms . BindingMode, Xamarin.Forms . Биндаблепроперти. Валидатевалуеделегате, Xamarin.Forms . Биндаблепроперти. Биндингпропертичанжедделегате, Xamarin.Forms . Биндаблепроперти. Биндингпропертичангингделегате, Xamarin.Forms . Биндаблепроперти. Коерцевалуеделегате, Xamarin.Forms . Биндаблепроперти. Креатедефаултвалуеделегате)) перегрузки методов.The bindable property should be set to the returned value of one of the BindableProperty.Create method overloads. Объявление должно находиться в теле BindableObject производного класса, но за пределами определений элементов.The declaration should be within the body of BindableObject derived class, but outside of any member definitions.

При создании необходимо указать как минимум идентификатор BindableProperty , а также следующие параметры:At a minimum, an identifier must be specified when creating a BindableProperty, along with the following parameters:

  • Имя BindableProperty .The name of the BindableProperty.
  • Тип свойства.The type of the property.
  • Тип объекта-владельца.The type of the owning object.
  • Значение по умолчанию для свойства.The default value for the property. Это гарантирует, что свойство всегда возвращает определенное значение по умолчанию, если оно не задано, и может отличаться от значения по умолчанию для типа свойства.This ensures that the property always returns a particular default value when it is unset, and it can be different from the default value for the type of the property. Значение по умолчанию будет восстановлено при [ ClearValue ] (xref: Xamarin.Forms . BindableObject. ClearValue ( Xamarin.Forms . Биндаблепроперти)) вызывается метод для свойства, доступного для привязки.The default value will be restored when the ClearValue method is called on the bindable property.

Важно!

Соглашение об именовании для свойств, допускающих привязку, заключается в том, что идентификатор связываемого свойства должен совпадать с именем свойства, указанным в Create методе, с добавлением к нему "Property".The naming convention for bindable properties is that the bindable property identifier must match the property name specified in the Create method, with "Property" appended to it.

В следующем коде показан пример привязываемого свойства с идентификатором и значениями для четырех обязательных параметров:The following code shows an example of a bindable property, with an identifier and values for the four required parameters:

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

При этом создается BindableProperty экземпляр с именем EventNameProperty типа string .This creates a BindableProperty instance named EventNameProperty, of type string. Свойство принадлежит EventToCommandBehavior классу и имеет значение по умолчанию null .The property is owned by the EventToCommandBehavior class, and has a default value of null.

При необходимости при создании BindableProperty экземпляра можно указать следующие параметры.Optionally, when creating a BindableProperty instance, the following parameters can be specified:

  • Режим привязки.The binding mode. Используется для указания направления, в котором изменения значения свойства будут распространены.This is used to specify the direction in which property value changes will propagate. В режиме привязки по умолчанию изменения будут распространяться от источника к целевому объекту.In the default binding mode, changes will propagate from the source to the target.
  • Делегат проверки, который будет вызываться, если задано значение свойства.A validation delegate that will be invoked when the property value is set. Дополнительные сведения см. в разделе обратные вызовы проверки.For more information, see Validation callbacks.
  • Измененное свойство делегат, который будет вызываться при изменении значения свойства.A property changed delegate that will be invoked when the property value has changed. Дополнительные сведения см. в разделе Обнаружение изменений свойств.For more information, see Detect property changes.
  • Изменяемое свойство делегата, которое будет вызываться при изменении значения свойства.A property changing delegate that will be invoked when the property value will change. Этот делегат имеет ту же сигнатуру, что и делегат, измененный свойством.This delegate has the same signature as the property changed delegate.
  • Приведенный делегат значения, который будет вызываться при изменении значения свойства.A coerce value delegate that will be invoked when the property value has changed. Дополнительные сведения см. в разделе приведение обратных вызовов к значению.For more information, see Coerce value callbacks.
  • Объект Func , используемый для инициализации значения свойства по умолчанию.A Func that's used to initialize a default property value. Дополнительные сведения см. в разделе Создание значения по умолчанию с помощью Func.For more information, see Create a default value with a Func.

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

Для доступа к связываемому свойству методы доступа к свойствам должны использовать синтаксис свойства.Property accessors are required to use property syntax to access a bindable property. GetМетод доступа должен возвращать значение, содержащееся в соответствующем связываемом свойстве.The Get accessor should return the value that's contained in the corresponding bindable property. Это можно сделать, вызвав [ GetValue ] (xref: Xamarin.Forms . BindableObject. GetValue ( Xamarin.Forms . Биндаблепроперти)), передав идентификатор привязываемого свойства для получения значения, а затем приведя результат к требуемому типу.This can be achieved by calling the GetValue method, passing in the bindable property identifier on which to get the value, and then casting the result to the required type. SetМетод доступа должен задавать значение соответствующего привязываемого свойства.The Set accessor should set the value of the corresponding bindable property. Это можно сделать, вызвав [ SetValue ] (xref: Xamarin.Forms . BindableObject. SetValue ( Xamarin.Forms . Биндаблепроперти, System. Object)), передавая идентификатор привязываемого свойства, для которого задается значение, и задаваемый значение.This can be achieved by calling the SetValue method, passing in the bindable property identifier on which to set the value, and the value to set.

В следующем примере кода показаны методы доступа для EventName привязываемого свойства:The following code example shows accessors for the EventName bindable property:

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

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

После создания свойства, доступного для привязки, его можно использовать из XAML или кода.Once a bindable property has been created, it can be consumed from XAML or code. В XAML это достигается путем объявления пространства имен с префиксом с помощью объявления пространства имен, указывающего имя пространства имен CLR, и, при необходимости, имени сборки.In XAML, this is achieved by declaring a namespace with a prefix, with the namespace declaration indicating the CLR namespace name, and optionally, an assembly name. Дополнительные сведения см. в разделе пространства имен XAML.For more information, see XAML Namespaces.

В следующем примере кода показано пространство имен XAML для пользовательского типа, который содержит свойство, доступное для привязки, которое определено в той же сборке, что и код приложения, ссылающийся на пользовательский тип:The following code example demonstrates a XAML namespace for a custom type that contains a bindable property, which is defined within the same assembly as the application code that's referencing the custom type:

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

Объявление пространства имен используется при задании свойства, доступного для EventName привязки, как показано в следующем примере кода XAML:The namespace declaration is used when setting the EventName bindable property, as demonstrated in the following XAML code example:

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

Эквивалентный код на языке C# показан в следующем примере:The equivalent C# code is shown in the following code example:

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

Сложные сценарииAdvanced scenarios

При создании BindableProperty экземпляра существует ряд необязательных параметров, которые можно задать для включения расширенных сценариев свойств с возможностью привязки.When creating a BindableProperty instance, there are a number of optional parameters that can be set to enable advanced bindable property scenarios. В этом разделе рассматриваются эти сценарии.This section explores these scenarios.

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

staticМетод обратного вызова, измененный свойством, можно зарегистрировать с помощью свойства, доступного для привязки, указав propertyChanged параметр для [ BindableProperty.Create ] (xref: Xamarin.Forms . Биндаблепроперти. Create (System. String, System. Type, System. Type, System. Object, Xamarin.Forms . BindingMode, Xamarin.Forms . Биндаблепроперти. Валидатевалуеделегате, Xamarin.Forms . Биндаблепроперти. Биндингпропертичанжедделегате, Xamarin.Forms . Биндаблепроперти. Биндингпропертичангингделегате, Xamarin.Forms . Биндаблепроперти. Коерцевалуеделегате, Xamarin.Forms . Биндаблепроперти. Креатедефаултвалуеделегате)).A static property-changed callback method can be registered with a bindable property by specifying the propertyChanged parameter for the BindableProperty.Create method. Указанный метод обратного вызова будет вызываться при изменении значения свойства, доступного для привязки.The specified callback method will be invoked when the value of the bindable property changes.

В следующем примере кода показано, как EventName свойство, поддерживающее привязку, регистрирует OnEventNameChanged метод в виде метода обратного вызова, измененного свойством:The following code example shows how the EventName bindable property registers the OnEventNameChanged method as a property-changed callback method:

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 параметров представляют старое и новое значения привязываемого свойства.In the property-changed callback method, the BindableObject parameter is used to denote which instance of the owning class has reported a change, and the values of the two object parameters represent the old and new values of the bindable property.

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

staticМетод обратного вызова проверки можно зарегистрировать с помощью свойства, доступного для привязки, указав validateValue параметр для [ BindableProperty.Create ] (xref: Xamarin.Forms . Биндаблепроперти. Create (System. String, System. Type, System. Type, System. Object, Xamarin.Forms . BindingMode, Xamarin.Forms . Биндаблепроперти. Валидатевалуеделегате, Xamarin.Forms . Биндаблепроперти. Биндингпропертичанжедделегате, Xamarin.Forms . Биндаблепроперти. Биндингпропертичангингделегате, Xamarin.Forms . Биндаблепроперти. Коерцевалуеделегате, Xamarin.Forms . Биндаблепроперти. Креатедефаултвалуеделегате)).A static validation callback method can be registered with a bindable property by specifying the validateValue parameter for the BindableProperty.Create method. Указанный метод обратного вызова будет вызываться, если задано значение свойства BIND.The specified callback method will be invoked when the value of the bindable property is set.

В следующем примере кода показано, как Angle свойство с возможностью привязки регистрирует IsValidValue метод в качестве метода обратного вызова проверки:The following code example shows how the Angle bindable property registers the IsValidValue method as a validation callback method:

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 .Validation callbacks are provided with a value, and should return true if the value is valid for the property, otherwise false. Если обратный вызов проверки возвращает значение false , которое должно обрабатываться разработчиком, возникнет исключение.An exception will be raised if a validation callback returns false, which should be handled by the developer. Типичное использование метода обратного вызова проверки ограничивает значения целых чисел или Double, если задано свойство, доступное для привязки.A typical use of a validation callback method is constraining the values of integers or doubles when the bindable property is set. Например, IsValidValue метод проверяет, что значение свойства находится в диапазоне от double 0 до 360.For example, the IsValidValue method checks that the property value is a double within the range 0 to 360.

Приведение обратных вызовов значенияCoerce value callbacks

staticПриведенный ниже метод обратного вызова значения можно зарегистрировать с помощью свойства, доступного для привязки, указав coerceValue параметр для [ BindableProperty.Create ] (xref: Xamarin.Forms . Биндаблепроперти. Create (System. String, System. Type, System. Type, System. Object, Xamarin.Forms . BindingMode, Xamarin.Forms . Биндаблепроперти. Валидатевалуеделегате, Xamarin.Forms . Биндаблепроперти. Биндингпропертичанжедделегате, Xamarin.Forms . Биндаблепроперти. Биндингпропертичангингделегате, Xamarin.Forms . Биндаблепроперти. Коерцевалуеделегате, Xamarin.Forms . Биндаблепроперти. Креатедефаултвалуеделегате)).A static coerce value callback method can be registered with a bindable property by specifying the coerceValue parameter for the BindableProperty.Create method. Указанный метод обратного вызова будет вызываться при изменении значения свойства, доступного для привязки.The specified callback method will be invoked when the value of the bindable property changes.

Важно!

BindableObjectТип имеет CoerceValue метод, который может быть вызван для принудительной повторной оценки значения его BindableProperty аргумента путем вызова обратного вызова приводимого значения.The BindableObject type has a CoerceValue method that can be called to force a reevaluation of the value of its BindableProperty argument, by invoking its coerce value callback.

Обратные вызовы приводимых значений используются для принудительного переоценки привязываемого свойства при изменении значения свойства.Coerce value callbacks are used to force a reevaluation of a bindable property when the value of the property changes. Например, можно использовать обратный вызов приводимого значения, чтобы убедиться, что значение одного связываемого свойства не больше значения другого привязываемого свойства.For example, a coerce value callback can be used to ensure that the value of one bindable property is not greater than the value of another bindable property.

В следующем примере кода показано, как Angle свойство с возможностью привязки регистрирует CoerceAngle метод в качестве метода обратного вызова для приведения значения:The following code example shows how the Angle bindable property registers the CoerceAngle method as a coerce value callback method:

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 значению свойства.The CoerceAngle method checks the value of the MaximumAngle property, and if the Angle property value is greater than it, it coerces the value to the MaximumAngle property value. Кроме того, при MaximumAngle изменении свойства функция обратного вызова приводимого значения вызывается для Angle свойства путем вызова CoerceValue метода.In addition, when the MaximumAngle property changes the coerce value callback is invoked on the Angle property by calling the CoerceValue method.

Создание значения по умолчанию с помощью FuncCreate a default value with a Func

FuncМожно использовать для инициализации значения по умолчанию привязываемого свойства, как показано в следующем примере кода:A Func can be used to initialize the default value of a bindable property, as demonstrated in the following code example:

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 ] (xref: Xamarin.Forms . Device. Жетнамедсизе ( Xamarin.Forms . Намедсизе, System. Type)) double , который возвращает, представляющий именованный размер шрифта, используемого на Label собственной платформе.The defaultValueCreator parameter is set to a Func that invokes the Device.GetNamedSize method to return a double that represents the named size for the font that is used on a Label on the native platform.