Passer des paramètres d’effet en tant que propriétés CLR (Common Language Runtime)
Les propriétés CLR (Common Language Runtime) permettent de définir des paramètres d’effet qui ne répondent pas aux changements apportés aux propriétés au moment de l’exécution. Cet article montre comment utiliser des propriétés CLR pour passer des paramètres à un effet.
Pour créer des paramètres d’effet qui ne répondent pas aux changements apportés aux propriétés au moment de l’exécution, suivez ces étapes :
- Créez une classe
public
qui sous-classe la classeRoutingEffect
. La classeRoutingEffect
représente un effet indépendant de la plateforme qui wrappe un effet interne généralement propre à une plateforme. - Créez un constructeur qui appelle le constructeur de classe de base, en passant une concaténation du nom du groupe de résolution, et l’ID unique qui a été spécifié sur la classe d’effet propre à chaque plateforme.
- Ajoutez des propriétés à la classe pour chaque paramètre à passer à l’effet.
Les paramètres peuvent ensuite être passés à l’effet en spécifiant des valeurs pour chaque propriété lors de l’instanciation de l’effet.
L’exemple d’application montre un ShadowEffect
qui ajoute une ombre au texte affiché par un contrôle Label
. 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 Label
sur HomePage
est personnalisé par LabelShadowEffect
dans chaque projet propre à la plateforme. Les paramètres sont passés à chaque LabelShadowEffect
par le biais des propriétés dans la classe ShadowEffect
. Chaque classe LabelShadowEffect
dérive de la classe PlatformEffect
pour chaque plateforme. Il en résulte l’ajout d’une ombre au texte affiché par le contrôle Label
, comme illustré dans les captures d’écran suivantes :
Création de paramètres d’effet
Une classe public
sous-classant la classe RoutingEffect
doit être créée pour représenter les paramètres d’effet, comme illustré dans l’exemple de code suivant :
public class ShadowEffect : RoutingEffect
{
public float Radius { get; set; }
public Color Color { get; set; }
public float DistanceX { get; set; }
public float DistanceY { get; set; }
public ShadowEffect () : base ("MyCompany.LabelShadowEffect")
{
}
}
LabelShadowEffect
contient quatre propriétés qui représentent les paramètres à passer à chaque ShadowEffect
propre à la plateforme. Le constructeur de classe appelle le constructeur de classe de base, en passant un paramètre constitué d’une concaténation du nom du groupe de résolution, et l’ID unique qui a été spécifié sur la classe d’effet propre à chaque plateforme. Par conséquent, une nouvelle instance de MyCompany.LabelShadowEffect
sera ajoutée à la collection Effects
d’un contrôle au moment de l’instanciation de ShadowEffect
.
Consommation de l’effet
L’exemple de code XAML suivant montre un contrôle Label
auquel est joint ShadowEffect
:
<Label Text="Label Shadow Effect" ...>
<Label.Effects>
<local:ShadowEffect Radius="5" DistanceX="5" DistanceY="5">
<local:ShadowEffect.Color>
<OnPlatform x:TypeArguments="Color">
<On Platform="iOS" Value="Black" />
<On Platform="Android" Value="White" />
<On Platform="UWP" Value="Red" />
</OnPlatform>
</local:ShadowEffect.Color>
</local:ShadowEffect>
</Label.Effects>
</Label>
Le contrôle Label
équivalent en C# est présenté dans l’exemple de code suivant :
var label = new Label {
Text = "Label Shadow Effect",
...
};
Color color = Color.Default;
switch (Device.RuntimePlatform)
{
case Device.iOS:
color = Color.Black;
break;
case Device.Android:
color = Color.White;
break;
case Device.UWP:
color = Color.Red;
break;
}
label.Effects.Add (new ShadowEffect {
Radius = 5,
Color = color,
DistanceX = 5,
DistanceY = 5
});
Dans les deux exemples de code, une instance de la classe ShadowEffect
est instanciée avec des valeurs spécifiées pour chaque propriété, avant d’être ajoutée à la collection Effects
du contrôle. Notez que la propriété ShadowEffect.Color
utilise des valeurs de couleur différentes pour chaque plateforme. Pour plus d’informations, consultez l’article sur la classe Device.
Création de l’effet sur chaque plateforme
Les sections suivantes décrivent l’implémentation de la classe LabelShadowEffect
pour chaque plateforme.
Projet iOS
L’exemple de code suivant illustre l’implémentation de LabelShadowEffect
pour le projet iOS :
[assembly:ResolutionGroupName ("MyCompany")]
[assembly:ExportEffect (typeof(LabelShadowEffect), "LabelShadowEffect")]
namespace EffectsDemo.iOS
{
public class LabelShadowEffect : PlatformEffect
{
protected override void OnAttached ()
{
try {
var effect = (ShadowEffect)Element.Effects.FirstOrDefault (e => e is ShadowEffect);
if (effect != null) {
Control.Layer.ShadowRadius = effect.Radius;
Control.Layer.ShadowColor = effect.Color.ToCGColor ();
Control.Layer.ShadowOffset = new CGSize (effect.DistanceX, effect.DistanceY);
Control.Layer.ShadowOpacity = 1.0f;
}
} catch (Exception ex) {
Console.WriteLine ("Cannot set property on attached control. Error: ", ex.Message);
}
}
protected override void OnDetached ()
{
}
}
}
La méthode OnAttached
récupère l’instance ShadowEffect
et définit les propriétés Control.Layer
sur les valeurs de propriété spécifiées pour créer l’ombre. Cette fonctionnalité est wrappée dans un bloc try
/catch
au cas où le contrôle auquel l’effet est joint n’a pas les propriétés Control.Layer
. Aucune implémentation n’est fournie par la méthode OnDetached
, car aucun nettoyage n’est nécessaire.
Projet Android
L’exemple de code suivant illustre l’implémentation de LabelShadowEffect
pour le projet Android :
[assembly:ResolutionGroupName ("MyCompany")]
[assembly:ExportEffect (typeof(LabelShadowEffect), "LabelShadowEffect")]
namespace EffectsDemo.Droid
{
public class LabelShadowEffect : PlatformEffect
{
protected override void OnAttached ()
{
try {
var control = Control as Android.Widget.TextView;
var effect = (ShadowEffect)Element.Effects.FirstOrDefault (e => e is ShadowEffect);
if (effect != null) {
float radius = effect.Radius;
float distanceX = effect.DistanceX;
float distanceY = effect.DistanceY;
Android.Graphics.Color color = effect.Color.ToAndroid ();
control.SetShadowLayer (radius, distanceX, distanceY, color);
}
} catch (Exception ex) {
Console.WriteLine ("Cannot set property on attached control. Error: ", ex.Message);
}
}
protected override void OnDetached ()
{
}
}
}
La méthode OnAttached
récupère l’instance ShadowEffect
et appelle la méthode TextView.SetShadowLayer
pour créer une ombre en utilisant les valeurs de propriété spécifiées. Cette fonctionnalité est wrappée dans un bloc try
/catch
au cas où le contrôle auquel l’effet est joint n’a pas les propriétés Control.Layer
. Aucune implémentation n’est fournie par la méthode OnDetached
, car aucun nettoyage n’est nécessaire.
Projet de plateforme Windows universelle
L’exemple de code suivant montre l’implémentation de LabelShadowEffect
pour le projet de plateforme Windows universelle (UWP) :
[assembly: ResolutionGroupName ("Xamarin")]
[assembly: ExportEffect (typeof(LabelShadowEffect), "LabelShadowEffect")]
namespace EffectsDemo.UWP
{
public class LabelShadowEffect : PlatformEffect
{
bool shadowAdded = false;
protected override void OnAttached ()
{
try {
if (!shadowAdded) {
var effect = (ShadowEffect)Element.Effects.FirstOrDefault (e => e is ShadowEffect);
if (effect != null) {
var textBlock = Control as Windows.UI.Xaml.Controls.TextBlock;
var shadowLabel = new Label ();
shadowLabel.Text = textBlock.Text;
shadowLabel.FontAttributes = FontAttributes.Bold;
shadowLabel.HorizontalOptions = LayoutOptions.Center;
shadowLabel.VerticalOptions = LayoutOptions.CenterAndExpand;
shadowLabel.TextColor = effect.Color;
shadowLabel.TranslationX = effect.DistanceX;
shadowLabel.TranslationY = effect.DistanceY;
((Grid)Element.Parent).Children.Insert (0, shadowLabel);
shadowAdded = true;
}
}
} catch (Exception ex) {
Debug.WriteLine ("Cannot set property on attached control. Error: ", ex.Message);
}
}
protected override void OnDetached ()
{
}
}
}
La plateforme Windows universelle ne fournissant pas d’effet d’ombre, l’implémentation de LabelShadowEffect
sur les deux plateformes en simule un en ajoutant un deuxième décalage Label
derrière le contrôle Label
principal. La méthode OnAttached
récupère l’instance ShadowEffect
, crée le nouveau contrôle Label
et définit certaines propriétés de disposition sur Label
. Elle crée ensuite l’ombre en définissant les propriétés TextColor
, TranslationX
et TranslationY
qui contrôlent la couleur et l’emplacement de Label
. Le contrôle shadowLabel
est alors inséré en décalage derrière le contrôle Label
principal. Cette fonctionnalité est wrappée dans un bloc try
/catch
au cas où le contrôle auquel l’effet est joint n’a pas les propriétés Control.Layer
. Aucune implémentation n’est fournie par la méthode OnDetached
, car aucun nettoyage n’est nécessaire.
Résumé
Cet article a montré comment utiliser des propriétés CLR pour passer des paramètres à un effet. Les propriétés CLR permettent de définir des paramètres d’effet qui ne répondent pas aux changements apportés aux propriétés au moment de l’exécution.