Attached Behaviors
Attached behaviors are static classes with one or more attached properties. This article demonstrates how to create and consume attached behaviors.
Overview
An attached property is a special type of bindable property. They are defined in one class but attached to other objects, and they are recognizable in XAML as attributes that contain a class and a property name separated by a period.
An attached property can define a propertyChanged
delegate that will be executed when the value of the property changes, such as when the property is set on a control. When the propertyChanged
delegate executes, it's passed a reference to the control on which it is being attached, and parameters that contain the old and new values for the property. This delegate can be used to add new functionality to the control that the property is attached to by manipulating the reference that is passed in, as follows:
- The
propertyChanged
delegate casts the control reference, which is received as aBindableObject
, to the control type that the behavior is designed to enhance. - The
propertyChanged
delegate modifies properties of the control, calls methods of the control, or registers event handlers for events exposed by the control, to implement the core behavior functionality.
An issue with attached behaviors is that they are defined in a static
class, with static
properties and methods. This makes it difficult to create attached behaviors that have state. In addition, Xamarin.Forms behaviors have replaced attached behaviors as the preferred approach to behavior construction. For more information about Xamarin.Forms behaviors, see Xamarin.Forms Behaviors.
Creating an Attached Behavior
The sample application demonstrates a NumericValidationBehavior
, which highlights the value entered by the user into an Entry
control in red, if it's not a double
. The behavior is shown in the following code example:
public static class NumericValidationBehavior
{
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.TextChanged += OnEntryTextChanged;
} else {
entry.TextChanged -= OnEntryTextChanged;
}
}
static void OnEntryTextChanged (object sender, TextChangedEventArgs args)
{
double result;
bool isValid = double.TryParse (args.NewTextValue, out result);
((Entry)sender).TextColor = isValid ? Color.Default : Color.Red;
}
}
The NumericValidationBehavior
class contains an attached property named AttachBehavior
with a static
getter and setter, which controls the addition or removal of the behavior to the control to which it will be attached. This attached property registers the OnAttachBehaviorChanged
method that will be executed when the value of the property changes. This method registers or de-registers an event handler for the TextChanged
event, based on the value of the AttachBehavior
attached property. The core functionality of the behavior is provided by the OnEntryTextChanged
method, which parses the value entered into the Entry
by the user, and sets the TextColor
property to red if the value isn't a double
.
Consuming an Attached Behavior
The NumericValidationBehavior
class can be consumed by adding the AttachBehavior
attached property to an Entry
control, as demonstrated in the following XAML code example:
<ContentPage ... xmlns:local="clr-namespace:WorkingWithBehaviors;assembly=WorkingWithBehaviors" ...>
...
<Entry Placeholder="Enter a System.Double" local:NumericValidationBehavior.AttachBehavior="true" />
...
</ContentPage>
The equivalent Entry
in C# is shown in the following code example:
var entry = new Entry { Placeholder = "Enter a System.Double" };
NumericValidationBehavior.SetAttachBehavior (entry, true);
At runtime, the behavior will respond to interaction with the control, according to the behavior implementation. The following screenshots demonstrate the attached behavior responding to invalid input:
Note
Attached behaviors are written for a specific control type (or a superclass that can apply to many controls), and they should only be added to a compatible control. Attempting to attach a behavior to an incompatible control will result in unknown behavior, and depends on the behavior implementation.
Removing an Attached Behavior from a Control
The NumericValidationBehavior
class can be removed from a control by setting the AttachBehavior
attached property to false
, as demonstrated in the following XAML code example:
<Entry Placeholder="Enter a System.Double" local:NumericValidationBehavior.AttachBehavior="false" />
The equivalent Entry
in C# is shown in the following code example:
var entry = new Entry { Placeholder = "Enter a System.Double" };
NumericValidationBehavior.SetAttachBehavior (entry, false);
At runtime, the OnAttachBehaviorChanged
method will be executed when the value of the AttachBehavior
attached property is set to false
. The OnAttachBehaviorChanged
method will then de-register the event handler for the TextChanged
event, ensuring that the behavior isn't executed as the user interacts with the control.
Summary
This article demonstrated how to create and consume attached behaviors. Attached behaviors are static
classes with one or more attached properties.