Creazione di un effetto
Gli effetti semplificano la personalizzazione di un controllo. Questo articolo spiega come creare un effetto che cambia il colore di sfondo del controllo Entry quando il controllo riceve lo stato attivo.
Il processo per la creazione di un effetto in ogni progetto specifico della piattaforma è come segue:
- Creare una sottoclasse della classe
PlatformEffect
. - Eseguire l'override del metodo
OnAttached
scrivere la logica per personalizzare il controllo. - Eseguire l'override del metodo
OnDetached
e scrivere la logica per pulire la personalizzazione del controllo, se necessario. - Aggiungere un attributo
ResolutionGroupName
alla classe di effetto. Questo attributo imposta uno spazio dei nomi a livello di società per gli effetti, per evitare che si verifichino conflitti con altri effetti omonimi. Si noti che questo attributo può essere applicato solo una volta per ogni progetto. - Aggiungere un attributo
ExportEffect
alla classe di effetto. Questo attributo registra l'effetto con un ID univoco usato da Xamarin.Forms, insieme al nome del gruppo, per individuare l'effetto prima di applicarlo a un controllo. L'attributo accetta due parametri: il nome del tipo di effetto e una stringa univoca che consente di individuare l'effetto prima di applicarlo a un controllo.
L'effetto può quindi essere utilizzato associandolo al controllo appropriato.
Nota
La specifica di un effetto nel progetto di ogni piattaforma è facoltativa. Se si tenta di usare un effetto quando non ne sono stati registrati, verrà restituito un valore non null che non esegue alcuna operazione.
L'applicazione di esempio illustra un FocusEffect
che cambia il colore di sfondo di un controllo quando ottiene lo stato attivo. Il diagramma seguente illustra le responsabilità di ogni progetto nell'applicazione di esempio, insieme alle relazioni tra di essi:
Un controllo Entry
in HomePage
è personalizzato dalla classe FocusEffect
in ogni progetto specifico della piattaforma. Ogni classe FocusEffect
deriva dalla classe PlatformEffect
per ogni piattaforma. Di conseguenza il rendering di ogni controllo Entry
viene eseguito con un colore di sfondo specifico della piattaforma, che cambia quando il controllo ottiene lo stato attivo, come illustrato negli screenshot seguenti:
Creazione dell'effetto in ogni piattaforma
Le sezioni seguenti illustrano l'implementazione specifica della piattaforma della classe FocusEffect
.
Progetto iOS
L'esempio di codice seguente mostra l'implementazione di FocusEffect
per il progetto 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);
}
}
}
}
Il metodoOnAttached
imposta la proprietà BackgroundColor
del controllo su viola chiaro con il metodo UIColor.FromRGB
e archivia questo colore in un campo. Questa funzionalità è incapsulata in un blocco try
/catch
, nell'evenienza in cui il controllo a cui l'effetto è associato non avesse una proprietà BackgroundColor
. Il metodo OnDetached
non fornisce alcuna implementazione perché non sono necessarie operazioni di pulizia.
L'override OnElementPropertyChanged
risponde alle modifiche alle proprietà associabili nel Xamarin.Forms controllo . Quando la proprietà IsFocused
cambia, la proprietà BackgroundColor
del controllo imposta bianco, se il controllo ha lo stato attivo, oppure viola chiaro in caso contrario. Questa funzionalità è incapsulata in un blocco try
/catch
, nell'evenienza in cui il controllo a cui l'effetto è associato non avesse una proprietà BackgroundColor
.
Progetto Android
L'esempio di codice seguente mostra l'implementazione di FocusEffect
per il progetto 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);
}
}
}
}
Il metodo OnAttached
esegue una chiamata al metodo SetBackgroundColor
per impostare il colore di sfondo del controllo su verde chiaro e archivia anche questo colore in un campo. Questa funzionalità è incapsulata in un blocco try
/catch
, nell'evenienza in cui il controllo a cui l'effetto è associato non avesse una proprietà SetBackgroundColor
. Il metodo OnDetached
non fornisce alcuna implementazione perché non sono necessarie operazioni di pulizia.
L'override OnElementPropertyChanged
risponde alle modifiche alle proprietà associabili nel Xamarin.Forms controllo . Quando la proprietà IsFocused
cambia, il colore di sfondo del controllo imposta bianco, se il controllo ha lo stato attivo, oppure verde chiaro in caso contrario. Questa funzionalità è incapsulata in un blocco try
/catch
, nell'evenienza in cui il controllo a cui l'effetto è associato non avesse una proprietà BackgroundColor
.
Progetti della piattaforma UWP (Universal Windows Platform)
L'esempio di codice seguente mostra l'implementazione di FocusEffect
per il progetto UWP (Universal Windows Platform):
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()
{
}
}
}
Il metodo OnAttached
imposta la proprietà Background
del controllo su ciano e imposta la proprietà BackgroundFocusBrush
su bianco. Questa funzionalità è incapsulata in un blocco try
/catch
, nell'evenienza in cui il controllo a cui l'effetto è associato non avesse queste proprietà. Il metodo OnDetached
non fornisce alcuna implementazione perché non sono necessarie operazioni di pulizia.
Utilizzo dell'effetto
Il processo per l'utilizzo di un effetto da una libreria .NET Standard o da un Xamarin.Forms progetto di libreria condivisa è il seguente:
- Dichiarare un controllo che verrà personalizzato dall'effetto.
- Associare l'effetto al controllo aggiungendolo alla raccolta
Effects
del controllo.
Nota
Un'istanza dell'effetto può essere associata solo a un singolo controllo. Pertanto, per poter essere usato su due controlli, un effetto deve essere risolto due volte.
Utilizzo dell'effetto in XAML
L'esempio di codice XAML seguente mostra un controllo Entry
a cui è associato FocusEffect
:
<Entry Text="Effect attached to an Entry" ...>
<Entry.Effects>
<local:FocusEffect />
</Entry.Effects>
...
</Entry>
La classe FocusEffect
nella libreria .NET Standard supporta l'utilizzo dell'effetto in XAML, come viene illustrato nell'esempio di codice seguente:
public class FocusEffect : RoutingEffect
{
public FocusEffect () : base ($"MyCompany.{nameof(FocusEffect)}")
{
}
}
La classe FocusEffect
crea una sottoclasse della classe RoutingEffect
, che rappresenta un effetto indipendente dalla piattaforma che esegue il wrapping di un effetto interno, in genere specifico della piattaforma. La classe FocusEffect
chiama il costruttore della classe di base, passando un parametro costituito da una concatenazione del nome del gruppo di risoluzione, specificato usando l'attributo ResolutionGroupName
della classe di effetto, e dell'ID univoco specificato usando l'attributo ExportEffect
sulla classe di effetto. Pertanto, quando il controllo Entry
viene inizializzato in fase di esecuzione, una nuova istanza di MyCompany.FocusEffect
viene aggiunta alla raccolta Effects
del controllo.
Gli effetti possono inoltre essere associati ai controlli per mezzo di un comportamento o utilizzando le proprietà associate. Per altre informazioni sull'associazione di un effetto a un controllo utilizzando un comportamento, vedere Reusable EffectBehavior (EffectBehavior riutilizzabile). Per altre informazioni sull'associazione di un effetto a un controllo usando le proprietà associate, vedere Passing Parameters to an Effect (Passare parametri a un effetto).
Utilizzo dell'effetto in C#
Il codice C# equivalente per Entry
è visualizzato nell'esempio seguente:
var entry = new Entry {
Text = "Effect attached to an Entry",
...
};
FocusEffect
viene associato all'istanza di Entry
aggiungendo l'effetto alla raccolta Effects
del controllo, come illustrato nell'esempio di codice seguente:
public HomePageCS ()
{
...
entry.Effects.Add (Effect.Resolve ($"MyCompany.{nameof(FocusEffect)}"));
...
}
Effect.Resolve
restituisce un valore Effect
per il nome specificato, costituito da una concatenazione del nome del gruppo di risoluzione, specificato usando l'attributo ResolutionGroupName
della classe di effetto, e dell'ID univoco specificato usando l'attributo ExportEffect
sulla classe di effetto. Se una piattaforma non fornisce l'effetto, il metodo Effect.Resolve
restituirà un valore non null
.
Riepilogo
Questo articolo ha spiegato come creare un effetto che cambia il colore di sfondo del controllo Entry
quando il controllo riceve lo stato attivo.