Création d’un effet
Les effets simplifient la personnalisation d’un contrôle. Cet article montre comment créer un effet qui change la couleur d’arrière-plan du contrôle Entry quand le contrôle obtient le focus.
Le processus de création d’un effet dans chaque projet spécifique à une plateforme est le suivant :
- Créez une sous-classe de la classe
PlatformEffect
. - Remplacez la méthode
OnAttached
et écrivez une logique pour personnaliser le contrôle. - Remplacez la méthode
OnDetached
et écrivez si nécessaire une logique pour nettoyer la personnalisation du contrôle. - Ajoutez un attribut
ResolutionGroupName
à la classe de l’effet. Cet attribut définit un espace de noms à l’échelle de l’entreprise pour les effets, empêchant des collisions avec d’autres effets du même nom. Notez que cet attribut peut être appliqué seulement une fois par projet. - Ajoutez un attribut
ExportEffect
à la classe de l’effet. Cet attribut inscrit l’effet avec un ID unique utilisé par Xamarin.Forms, ainsi que le nom du groupe, pour localiser l’effet avant de l’appliquer à un contrôle. L’attribut prend deux paramètres : le nom de type de l’effet et une chaîne unique qui est utilisée pour localiser l’effet avant de l’appliquer à un contrôle.
L’effet peut ensuite être consommé en l’attachant au contrôle approprié.
Remarque
Fournir un effet dans chaque projet de plateforme est facultatif. Une tentative d’utiliser un effet quand il n’est pas inscrit retourne une valeur non null qui ne fait rien.
L’exemple d’application montre un FocusEffect
qui change la couleur d’arrière-plan d’un contrôle quand il obtient le focus. Le diagramme suivant illustre les responsabilités de chaque projet dans l’exemple d’application ainsi que les relations qu’ils entretiennent les uns avec les autres :
Un contrôle Entry
sur la page HomePage
est personnalisé par la classe FocusEffect
dans chaque projet spécifique à une plateforme. Chaque classe FocusEffect
dérive de la classe PlatformEffect
pour chaque plateforme. Il en résulte un rendu du contrôle Entry
avec une couleur d’arrière-plan spécifique à la plateforme, qui change quand le contrôle obtient le focus, comme le montrent les captures d’écran suivantes :
Création de l’effet sur chaque plateforme
Les sections suivantes décrivent l’implémentation de la classe FocusEffect
pour chaque plateforme.
Projet iOS
L’exemple de code suivant illustre l’implémentation de FocusEffect
pour le projet iOS :
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly:ResolutionGroupName ("MyCompany")]
[assembly:ExportEffect (typeof(EffectsDemo.iOS.FocusEffect), nameof(EffectsDemo.iOS.FocusEffect))]
namespace EffectsDemo.iOS
{
public class FocusEffect : PlatformEffect
{
UIColor backgroundColor;
protected override void OnAttached ()
{
try {
Control.BackgroundColor = backgroundColor = UIColor.FromRGB (204, 153, 255);
} catch (Exception ex) {
Console.WriteLine ("Cannot set property on attached control. Error: ", ex.Message);
}
}
protected override void OnDetached ()
{
}
protected override void OnElementPropertyChanged (PropertyChangedEventArgs args)
{
base.OnElementPropertyChanged (args);
try {
if (args.PropertyName == "IsFocused") {
if (Control.BackgroundColor == backgroundColor) {
Control.BackgroundColor = UIColor.White;
} else {
Control.BackgroundColor = backgroundColor;
}
}
} catch (Exception ex) {
Console.WriteLine ("Cannot set property on attached control. Error: ", ex.Message);
}
}
}
}
La méthode OnAttached
définit la propriété BackgroundColor
sur la couleur « light purple » (violet clair) avec la méthode UIColor.FromRGB
et stocke également cette couleur dans un champ. Cette fonctionnalité est wrappée dans un bloc try
/catch
, au cas où le contrôle auquel l’effet est attaché n’aurait pas de propriété BackgroundColor
. Aucune implémentation n’est fournie par la méthode OnDetached
, car aucun nettoyage n’est nécessaire.
Le OnElementPropertyChanged
remplacement répond aux modifications de propriété pouvant être liées sur le Xamarin.Forms contrôle. Quand la propriété IsFocused
change, la propriété BackgroundColor
du contrôle est changée en « white » (blanc) si le contrôle a le focus, sinon il est changé en « light purple » (violet clair). Cette fonctionnalité est wrappée dans un bloc try
/catch
, au cas où le contrôle auquel l’effet est attaché n’aurait pas de propriété BackgroundColor
.
Projet Android
L’exemple de code suivant illustre l’implémentation de FocusEffect
pour le projet Android :
using System;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ResolutionGroupName("MyCompany")]
[assembly: ExportEffect(typeof(EffectsDemo.Droid.FocusEffect), nameof(EffectsDemo.Droid.FocusEffect))]
namespace EffectsDemo.Droid
{
public class FocusEffect : PlatformEffect
{
Android.Graphics.Color originalBackgroundColor = new Android.Graphics.Color(0, 0, 0, 0);
Android.Graphics.Color backgroundColor;
protected override void OnAttached()
{
try
{
backgroundColor = Android.Graphics.Color.LightGreen;
Control.SetBackgroundColor(backgroundColor);
}
catch (Exception ex)
{
Console.WriteLine("Cannot set property on attached control. Error: ", ex.Message);
}
}
protected override void OnDetached()
{
}
protected override void OnElementPropertyChanged(System.ComponentModel.PropertyChangedEventArgs args)
{
base.OnElementPropertyChanged(args);
try
{
if (args.PropertyName == "IsFocused")
{
if (((Android.Graphics.Drawables.ColorDrawable)Control.Background).Color == backgroundColor)
{
Control.SetBackgroundColor(originalBackgroundColor);
}
else
{
Control.SetBackgroundColor(backgroundColor);
}
}
}
catch (Exception ex)
{
Console.WriteLine("Cannot set property on attached control. Error: ", ex.Message);
}
}
}
}
La méthode OnAttached
appelle la méthode SetBackgroundColor
pour définir la couleur d’arrière-plan du contrôle en vert clair et stocke également cette couleur dans un champ. Cette fonctionnalité est wrappée dans un bloc try
/catch
, au cas où le contrôle auquel l’effet est attaché n’aurait pas de propriété SetBackgroundColor
. Aucune implémentation n’est fournie par la méthode OnDetached
, car aucun nettoyage n’est nécessaire.
Le OnElementPropertyChanged
remplacement répond aux modifications de propriété pouvant être liées sur le Xamarin.Forms contrôle. Quand la propriété IsFocused
change, la couleur d’arrière-plan du contrôle est changée en « white » (blanc) si le contrôle a le focus, sinon il est changé en « light green » (vert clair). Cette fonctionnalité est wrappée dans un bloc try
/catch
, au cas où le contrôle auquel l’effet est attaché n’aurait pas de propriété BackgroundColor
.
Projets UWP (Plateforme Windows universelle)
L’exemple de code suivant montre l’implémentation de FocusEffect
pour le projet de plateforme UWP :
using Xamarin.Forms;
using Xamarin.Forms.Platform.UWP;
[assembly: ResolutionGroupName("MyCompany")]
[assembly: ExportEffect(typeof(EffectsDemo.UWP.FocusEffect), nameof(EffectsDemo.UWP.FocusEffect))]
namespace EffectsDemo.UWP
{
public class FocusEffect : PlatformEffect
{
protected override void OnAttached()
{
try
{
(Control as Windows.UI.Xaml.Controls.Control).Background = new SolidColorBrush(Colors.Cyan);
(Control as FormsTextBox).BackgroundFocusBrush = new SolidColorBrush(Colors.White);
}
catch (Exception ex)
{
Debug.WriteLine("Cannot set property on attached control. Error: ", ex.Message);
}
}
protected override void OnDetached()
{
}
}
}
La méthode OnAttached
définit la propriété Background
du contrôle sur « cyan » et définit la propriété BackgroundFocusBrush
sur « white » (blanc). Cette fonctionnalité est wrappée dans un bloc try
/catch
, au cas où le contrôle auquel l’effet est attaché n’aurait pas ces propriétés. Aucune implémentation n’est fournie par la méthode OnDetached
, car aucun nettoyage n’est nécessaire.
Consommation de l’effet
Le processus de consommation d’un effet à partir d’une bibliothèque .NET Standard ou d’un Xamarin.Forms projet de bibliothèque partagée est le suivant :
- Déclarez un contrôle qui sera personnalisé par l’effet.
- Attachez l’effet au contrôle en l’ajoutant à la collection
Effects
du contrôle.
Remarque
Une instance de l’effet ne peut être attachée qu’à un seul contrôle. Par conséquent, un effet doit être résolu deux fois pour être utilisé sur deux contrôles.
Consommation de l’effet en XAML
L’exemple de code XAML suivant montre un contrôle Entry
auquel FocusEffect
est attaché :
<Entry Text="Effect attached to an Entry" ...>
<Entry.Effects>
<local:FocusEffect />
</Entry.Effects>
...
</Entry>
La classe FocusEffect
de la bibliothèque .NET Standard prend en charge la consommation d’effets en XAML et elle apparaît dans l’exemple de code suivant :
public class FocusEffect : RoutingEffect
{
public FocusEffect () : base ($"MyCompany.{nameof(FocusEffect)}")
{
}
}
La classe FocusEffect
crée une sous-classe de la classe RoutingEffect
, qui représente un effet indépendant de la plateforme qui wrappe un effet interne généralement spécifique à une plateforme. La classe FocusEffect
appelle le constructeur de classe de base, en passant un paramètre constitué d’une concaténation du nom du groupe de résolution (spécifié avec l’attribut ResolutionGroupName
sur la classe d’effet), et l’ID unique qui a été spécifié avec l’attribut ExportEffect
sur la classe d’effet. Par conséquent, quand Entry
est initialisé à l’exécution, une nouvelle instance de MyCompany.FocusEffect
est ajoutée à la collection Effects
du contrôle.
Les effets peuvent également être attachés à des contrôles avec un comportement ou avec des propriétés attachées. Pour plus d’informations sur l’attachement d’un effet à un contrôle avec un comportement, consultez Comportement d’effet réutilisable. Pour plus d’informations sur l’attachement d’un effet à un contrôle avec des propriétés attachées, consultez Passage de paramètres à un effet.
Consommation de l’effet en C#
Le contrôle Entry
équivalent en C# est présenté dans l’exemple de code suivant :
var entry = new Entry {
Text = "Effect attached to an Entry",
...
};
FocusEffect
est attaché à la l’instance de Entry
en ajoutant l’effet à la collection Effects
du contrôle, comme illustré dans l’exemple de code suivant :
public HomePageCS ()
{
...
entry.Effects.Add (Effect.Resolve ($"MyCompany.{nameof(FocusEffect)}"));
...
}
Effect.Resolve
retourne un Effect
pour le nom spécifié, qui est une concaténation du nom du groupe de résolution (spécifié avec l’attribut ResolutionGroupName
sur la classe d’effet), et l’ID unique qui a été spécifié avec l’attribut ExportEffect
sur la classe d’effet. Si une plateforme ne fournit pas l’effet, la méthode Effect.Resolve
retourne une valeur non null
.
Résumé
Cet article montre comment créer un effet qui change la couleur d’arrière-plan du contrôle Entry
quand le contrôle obtient le focus.