Personalizzazione di un elemento WebView
È Xamarin.FormsWebView
una visualizzazione che visualizza il contenuto Web e HTML nell'app. Questo articolo illustra come creare un renderer personalizzato che estende per WebView
consentire la chiamata del codice C# da JavaScript.
Ogni Xamarin.Forms visualizzazione ha un renderer a discesa per ogni piattaforma che crea un'istanza di un controllo nativo. WebView
Quando un oggetto viene sottoposto a rendering da un'applicazione Xamarin.Forms in iOS, viene creata un'istanza della WkWebViewRenderer
classe , che a sua volta crea un'istanza di un controllo nativoWkWebView
. Nella piattaforma Android la classe WebViewRenderer
crea un'istanza di un controllo WebView
nativo. Nella piattaforma UWP (Universal Windows Platform) la classe WebViewRenderer
crea un'istanza di un controllo WebView
nativo. Per altre informazioni sulle classi di controllo native e del renderer a cui Xamarin.Forms viene eseguito il mapping dei controlli, vedere Classi di base del renderer e controlli nativi.
Il diagramma seguente illustra la relazione tra la classe View
e i controlli nativi corrispondenti che la implementano:
Il processo di rendering può essere usato per implementare le personalizzazioni della piattaforma creando un renderer personalizzato per un oggetto WebView
in ogni piattaforma. Il processo per eseguire questa operazione è il seguente:
- Creare il controllo personalizzato
HybridWebView
. - Utilizzare da
HybridWebView
Xamarin.Forms. - Creare il renderer personalizzato per
HybridWebView
in ogni piattaforma.
Ogni elemento verrà ora illustrato a sua volta per implementare un HybridWebView
renderer che migliora per Xamarin.FormsWebView
consentire la chiamata del codice C# da JavaScript. L'istanza di HybridWebView
verrà usata per visualizzare una pagina HTML in cui viene chiesto all'utente di immettere il proprio nome. Quindi, quando l'utente fa clic su un pulsante HTML, una funzione JavaScript richiama un elemento Action
di C# che visualizza una finestra popup contenente il nome dell'utente.
Per altre informazioni sul processo per richiamare C# da JavaScript, vedere Richiamare C# da JavaScript. Per altre informazioni sulla pagina HTML, vedere Creare la pagina Web.
Nota
Un WebView
oggetto può richiamare una funzione JavaScript da C# e restituire qualsiasi risultato al codice C# chiamante. Per altre informazioni, vedere Richiamo di JavaScript.
Creare HybridWebView
Il HybridWebView
controllo personalizzato può essere creato sottoclassando la WebView
classe :
public class HybridWebView : WebView
{
Action<string> action;
public static readonly BindableProperty UriProperty = BindableProperty.Create(
propertyName: "Uri",
returnType: typeof(string),
declaringType: typeof(HybridWebView),
defaultValue: default(string));
public string Uri
{
get { return (string)GetValue(UriProperty); }
set { SetValue(UriProperty, value); }
}
public void RegisterAction(Action<string> callback)
{
action = callback;
}
public void Cleanup()
{
action = null;
}
public void InvokeAction(string data)
{
if (action == null || data == null)
{
return;
}
action.Invoke(data);
}
}
Il controllo personalizzato HybridWebView
viene creato nel progetto di libreria .NET Standard e definisce l'API seguente per il controllo:
- Una proprietà
Uri
che specifica l'indirizzo della pagina Web da caricare. - Un metodo
RegisterAction
che registra un elementoAction
con il controllo. L'azione registrata verrà richiamata da JavaScript all'interno del file HTML a cui si fa riferimento attraverso la proprietàUri
. - Un metodo
CleanUp
che rimuove il riferimento all'elementoAction
registrato. - Un metodo
InvokeAction
che richiama l'elementoAction
registrato. Questo metodo verrà chiamato da un renderer personalizzato in ogni progetto di piattaforma.
Usare HybridWebView
Per fare riferimento al controllo personalizzato HybridWebView
in XAML nel progetto di libreria .NET Standard, è possibile dichiarare uno spazio dei nomi per il percorso e usare il prefisso dello spazio dei nomi nel controllo personalizzato. Nell'esempio di codice riportato di seguito viene illustrato come il controllo personalizzato HybridWebView
può essere usato da una pagina XAML:
<ContentPage ...
xmlns:local="clr-namespace:CustomRenderer;assembly=CustomRenderer"
x:Class="CustomRenderer.HybridWebViewPage"
Padding="0,40,0,0">
<local:HybridWebView x:Name="hybridWebView"
Uri="index.html" />
</ContentPage>
Il prefisso dello spazio dei nomi local
può avere qualsiasi nome. I valori clr-namespace
e assembly
devono tuttavia corrispondere ai dettagli del controllo personalizzato. Dopo aver dichiarato lo spazio dei nomi, il prefisso viene usato per fare riferimento al controllo personalizzato.
Nell'esempio di codice riportato di seguito viene illustrato come il controllo personalizzato HybridWebView
può essere usato da una pagina C#:
public HybridWebViewPageCS()
{
var hybridWebView = new HybridWebView
{
Uri = "index.html"
};
// ...
Padding = new Thickness(0, 40, 0, 0);
Content = hybridWebView;
}
L'istanza di HybridWebView
verrà usata per visualizzare un controllo Web nativo in ogni piattaforma. La proprietà è Uri
impostata su un file HTML archiviato in ogni progetto di piattaforma e che verrà visualizzato dal controllo Web nativo. Il codice HTML sottoposto a rendering chiede all'utente di immettere il proprio nome, con una funzione JavaScript che richiama un elemento Action
di C# in risposta al clic su un pulsante HTML.
HybridWebViewPage
registra l'azione da richiamare da JavaScript, come illustra l'esempio di codice seguente:
public partial class HybridWebViewPage : ContentPage
{
public HybridWebViewPage()
{
// ...
hybridWebView.RegisterAction(data => DisplayAlert("Alert", "Hello " + data, "OK"));
}
}
Questa azione chiama il metodo DisplayAlert
per visualizzare un popup modale che presenta il nome immesso nella pagina HTML visualizzata dall'istanza di HybridWebView
.
È ora possibile aggiungere un renderer personalizzato a ogni progetto di applicazione per migliorare i controlli Web della piattaforma consentendo di richiamare il codice C# da JavaScript.
Creare il renderer personalizzato in ogni piattaforma
Il processo di creazione della classe di renderer personalizzato è il seguente:
- Creare una sottoclasse della
WkWebViewRenderer
classe in iOS e laWebViewRenderer
classe in Android e UWP, che esegue il rendering del controllo personalizzato. - Eseguire l'override del metodo che esegue il
OnElementChanged
rendering dellaWebView
logica e scrivere per personalizzarla. Questo metodo viene chiamato quando viene creato unHybridWebView
oggetto . - Aggiungere un
ExportRenderer
attributo alla classe o AssemblyInfo.cs del renderer personalizzato per specificare che verrà usato per eseguire il rendering del Xamarin.Forms controllo personalizzato. Questo attributo viene usato per registrare il renderer personalizzato con Xamarin.Forms.
Nota
Per la maggior parte degli Xamarin.Forms elementi, è facoltativo fornire un renderer personalizzato in ogni progetto di piattaforma. Se un renderer personalizzato non è registrato, verrà usato il renderer predefinito per la classe di base del controllo. I renderer personalizzati sono tuttavia necessari in ogni progetto della piattaforma quando si esegue il rendering di un elemento View.
Il diagramma seguente illustra le responsabilità di ogni progetto nell'applicazione di esempio, insieme alle relazioni tra di essi:
Il rendering del HybridWebView
controllo personalizzato viene eseguito dalle classi renderer della piattaforma, che derivano dalla WkWebViewRenderer
classe in iOS e dalla WebViewRenderer
classe in Android e UWP. In questo modo viene eseguito il rendering di ogni HybridWebView
controllo personalizzato con controlli Web nativi, come illustrato negli screenshot seguenti:
Le WkWebViewRenderer
classi e WebViewRenderer
espongono il OnElementChanged
metodo , che viene chiamato quando viene creato il controllo personalizzato per eseguire il Xamarin.Forms rendering del controllo Web nativo corrispondente. Questo metodo accetta un VisualElementChangedEventArgs
parametro che contiene OldElement
le proprietà e NewElement
. Queste proprietà rappresentano l'elemento Xamarin.Forms a cui è stato associato il renderer e l'elemento Xamarin.Forms a cui è associato il renderer. Nell'applicazione di esempio la proprietà OldElement
sarà null
e la proprietà NewElement
conterrà un riferimento all'istanza di HybridWebView
.
Una versione sottoposta a override del OnElementChanged
metodo, in ogni classe renderer della piattaforma, è la posizione in cui eseguire la personalizzazione del controllo Web nativo. È possibile ottenere un riferimento al controllo di cui viene eseguito il Xamarin.Forms rendering tramite la Element
proprietà .
Ogni classe renderer personalizzata è decorata con un ExportRenderer
attributo che registra il renderer con Xamarin.Forms. L'attributo accetta due parametri, ovvero il nome del tipo del controllo personalizzato di cui viene eseguito il Xamarin.Forms rendering e il nome del tipo del renderer personalizzato. Il prefisso assembly
dell'attributo specifica che l'attributo viene applicato all'intero assembly.
Le sezioni seguenti illustrano la struttura della pagina Web caricata da ogni controllo Web nativo, il processo per richiamare C# da JavaScript e l'implementazione di questa funzionalità in ogni classe renderer personalizzata della piattaforma.
Creare la pagina Web
L'esempio di codice seguente illustra la pagina Web che verrà visualizzata dal controllo personalizzato HybridWebView
:
<html>
<body>
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<h1>HybridWebView Test</h1>
<br />
Enter name: <input type="text" id="name">
<br />
<br />
<button type="button" onclick="javascript: invokeCSCode($('#name').val());">Invoke C# Code</button>
<br />
<p id="result">Result:</p>
<script type="text/javascript">function log(str) {
$('#result').text($('#result').text() + " " + str);
}
function invokeCSCode(data) {
try {
log("Sending Data:" + data);
invokeCSharpAction(data);
}
catch (err) {
log(err);
}
}</script>
</body>
</html>
La pagina Web consente all'utente di immettere il proprio nome in un elemento input
e indica un elemento button
che richiama il codice C# quando viene selezionato. Il processo per eseguire questa operazione è il seguente:
- Quando l'utente fa clic sull'elemento
button
, viene chiamata la funzione JavaScriptinvokeCSCode
, con il valore dell'elementoinput
passato alla funzione. - La funzione
invokeCSCode
chiama la funzionelog
per visualizzare i dati inviati all'elementoAction
di C#. Chiama quindi il metodoinvokeCSharpAction
per richiamare l'elementoAction
di C#, passando il parametro ricevuto dall'elementoinput
.
La funzione JavaScript invokeCSharpAction
non è definita nella pagina Web e verrà inserita al suo interno da ogni renderer personalizzato.
In iOS questo file HTML si trova nella cartella del contenuto del progetto della piattaforma, con l'azione di compilazione BundleResource. In Android questo file HTML si trova nella cartella degli asset/del contenuto del progetto della piattaforma, con l'azione di compilazione AndroidAsset.
Richiamare C# da JavaScript
Il processo per richiamare C# da JavaScript è identico in ogni piattaforma:
- Il renderer personalizzato crea un controllo Web nativo e carica il file HTML specificato dalla proprietà
HybridWebView.Uri
. - Dopo che la pagina Web è stata caricata, il renderer personalizzato inserisce la funzione JavaScript
invokeCSharpAction
nella pagina Web. - Quando l'utente immette il proprio nome e fa clic sull'elemento HTML
button
, viene richiamata la funzioneinvokeCSCode
, che a sua volta richiama la funzioneinvokeCSharpAction
. - La funzione
invokeCSharpAction
richiama un metodo nel renderer personalizzato, che a sua volta richiama il metodoHybridWebView.InvokeAction
. - Il metodo
HybridWebView.InvokeAction
richiama l'elementoAction
registrato.
Le sezioni seguenti spiegano come viene implementato questo processo in ogni piattaforma.
Creare il renderer personalizzato in iOS
L'esempio di codice seguente illustra il renderer personalizzato per la piattaforma iOS:
[assembly: ExportRenderer(typeof(HybridWebView), typeof(HybridWebViewRenderer))]
namespace CustomRenderer.iOS
{
public class HybridWebViewRenderer : WkWebViewRenderer, IWKScriptMessageHandler
{
const string JavaScriptFunction = "function invokeCSharpAction(data){window.webkit.messageHandlers.invokeAction.postMessage(data);}";
WKUserContentController userController;
public HybridWebViewRenderer() : this(new WKWebViewConfiguration())
{
}
public HybridWebViewRenderer(WKWebViewConfiguration config) : base(config)
{
userController = config.UserContentController;
var script = new WKUserScript(new NSString(JavaScriptFunction), WKUserScriptInjectionTime.AtDocumentEnd, false);
userController.AddUserScript(script);
userController.AddScriptMessageHandler(this, "invokeAction");
}
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
userController.RemoveAllUserScripts();
userController.RemoveScriptMessageHandler("invokeAction");
HybridWebView hybridWebView = e.OldElement as HybridWebView;
hybridWebView.Cleanup();
}
if (e.NewElement != null)
{
string filename = Path.Combine(NSBundle.MainBundle.BundlePath, $"Content/{((HybridWebView)Element).Uri}");
LoadRequest(new NSUrlRequest(new NSUrl(filename, false)));
}
}
public void DidReceiveScriptMessage(WKUserContentController userContentController, WKScriptMessage message)
{
((HybridWebView)Element).InvokeAction(message.Body.ToString());
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
((HybridWebView)Element).Cleanup();
}
base.Dispose(disposing);
}
}
}
La classe HybridWebViewRenderer
carica la pagina Web specificata nella proprietà HybridWebView.Uri
in un controllo WKWebView
nativo e la funzione JavaScript invokeCSharpAction
viene inserita nella pagina Web. Dopo che l'utente immette il proprio nome e fa clic sull'elemento HTML button
, la funzione JavaScript invokeCSharpAction
viene eseguita, con il metodo DidReceiveScriptMessage
chiamato dopo che viene ricevuto un messaggio dalla pagina Web. A sua volta, questo metodo richiama il metodo HybridWebView.InvokeAction
, che richiama l'azione registrata per visualizzare l'elemento popup.
Questa funzionalità si rende disponibile come indicato di seguito:
- Il costruttore del renderer crea un
WkWebViewConfiguration
oggetto e recupera il relativoWKUserContentController
oggetto. L'oggettoWkUserContentController
consente la pubblicazione di messaggi e l'inserimento di script utente in una pagina Web. - Il costruttore renderer crea un
WKUserScript
oggetto che inserisce lainvokeCSharpAction
funzione JavaScript nella pagina Web dopo il caricamento della pagina Web. - Il costruttore renderer chiama il
WKUserContentController.AddUserScript
metodo per aggiungere l'oggettoWKUserScript
al controller del contenuto. - Il costruttore renderer chiama il
WKUserContentController.AddScriptMessageHandler
metodo per aggiungere un gestore di messaggi di script denominatoinvokeAction
all'oggettoWKUserContentController
, che causerà la definizione della funzionewindow.webkit.messageHandlers.invokeAction.postMessage(data)
JavaScript in tutti i frame in tutte leWebView
istanze che usano l'oggettoWKUserContentController
. - A condizione che il renderer personalizzato sia associato a un nuovo Xamarin.Forms elemento:
- Il metodo
WKWebView.LoadRequest
carica il file HTML specificato dalla proprietàHybridWebView.Uri
. Il codice specifica che il file è archiviato nella cartellaContent
del progetto. Quando viene visualizzata la pagina Web, la funzione JavaScriptinvokeCSharpAction
viene inserita nella pagina Web.
- Il metodo
- Le risorse vengono rilasciate quando l'elemento a cui è associato il renderer.
- L'elemento Xamarin.Forms viene pulito quando il renderer viene eliminato.
Nota
La classe WKWebView
è supportata solo in iOS 8 e versioni successive.
È anche necessario aggiornare Info.plist in modo da includere i valori seguenti:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Creare il renderer personalizzato in Android
L'esempio di codice seguente illustra il renderer personalizzato per la piattaforma Android:
[assembly: ExportRenderer(typeof(HybridWebView), typeof(HybridWebViewRenderer))]
namespace CustomRenderer.Droid
{
public class HybridWebViewRenderer : WebViewRenderer
{
const string JavascriptFunction = "function invokeCSharpAction(data){jsBridge.invokeAction(data);}";
Context _context;
public HybridWebViewRenderer(Context context) : base(context)
{
_context = context;
}
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
Control.RemoveJavascriptInterface("jsBridge");
((HybridWebView)Element).Cleanup();
}
if (e.NewElement != null)
{
Control.SetWebViewClient(new JavascriptWebViewClient(this, $"javascript: {JavascriptFunction}"));
Control.AddJavascriptInterface(new JSBridge(this), "jsBridge");
Control.LoadUrl($"file:///android_asset/Content/{((HybridWebView)Element).Uri}");
}
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
((HybridWebView)Element).Cleanup();
}
base.Dispose(disposing);
}
}
}
La classe HybridWebViewRenderer
carica la pagina Web specificata nella proprietà HybridWebView.Uri
in un controllo WebView
nativo e la funzione JavaScript invokeCSharpAction
viene inserita nella pagina Web, al termine del caricamento della pagina Web, con override di OnPageFinished
nella classe JavascriptWebViewClient
:
public class JavascriptWebViewClient : FormsWebViewClient
{
string _javascript;
public JavascriptWebViewClient(HybridWebViewRenderer renderer, string javascript) : base(renderer)
{
_javascript = javascript;
}
public override void OnPageFinished(WebView view, string url)
{
base.OnPageFinished(view, url);
view.EvaluateJavascript(_javascript, null);
}
}
Dopo che l'utente immette il proprio nome e fa clic sull'elemento HTML button
, viene eseguita la funzione JavaScript invokeCSharpAction
. Questa funzionalità si rende disponibile come indicato di seguito:
- A condizione che il renderer personalizzato sia associato a un nuovo Xamarin.Forms elemento:
- Il
SetWebViewClient
metodo imposta un nuovoJavascriptWebViewClient
oggetto come implementazione diWebViewClient
. - Il metodo
WebView.AddJavascriptInterface
inserisce una nuova istanza diJSBridge
nel frame principale del contesto JavaScript di WebView, denominandolajsBridge
. In questo modo è possibile accedere ai metodi presenti nella classeJSBridge
da JavaScript. - Il metodo
WebView.LoadUrl
carica il file HTML specificato dalla proprietàHybridWebView.Uri
. Il codice specifica che il file è archiviato nella cartellaContent
del progetto. - Nella classe
JavascriptWebViewClient
la funzione JavaScriptinvokeCSharpAction
viene inserita nella pagina Web al termine del caricamento della pagina.
- Il
- Le risorse vengono rilasciate quando l'elemento a cui è associato il renderer.
- L'elemento Xamarin.Forms viene pulito quando il renderer viene eliminato.
Quando viene eseguita, la funzione JavaScript invokeCSharpAction
a sua volta richiama il metodo JSBridge.InvokeAction
, come illustra l'esempio di codice seguente:
public class JSBridge : Java.Lang.Object
{
readonly WeakReference<HybridWebViewRenderer> hybridWebViewRenderer;
public JSBridge(HybridWebViewRenderer hybridRenderer)
{
hybridWebViewRenderer = new WeakReference<HybridWebViewRenderer>(hybridRenderer);
}
[JavascriptInterface]
[Export("invokeAction")]
public void InvokeAction(string data)
{
HybridWebViewRenderer hybridRenderer;
if (hybridWebViewRenderer != null && hybridWebViewRenderer.TryGetTarget(out hybridRenderer))
{
((HybridWebView)hybridRenderer.Element).InvokeAction(data);
}
}
}
La classe deve derivare da Java.Lang.Object
e i metodi esposti a JavaScript devono essere decorati con gli attributi [JavascriptInterface]
e [Export]
. Di conseguenza, quando la funzione JavaScript invokeCSharpAction
viene inserita nella pagina Web ed eseguita, chiama il metodo JSBridge.InvokeAction
poiché è decorata con gli attributi [JavascriptInterface]
e [Export("invokeAction")]
. A sua volta, il InvokeAction
metodo richiama il HybridWebView.InvokeAction
metodo , che richiama l'azione registrata per visualizzare il popup.
Importante
I progetti Android che usano l'attributo [Export]
devono includere un riferimento a Mono.Android.Export
oppure verrà generato un errore del compilatore.
Si noti che la classe JSBridge
mantiene un elemento WeakReference
per la classe HybridWebViewRenderer
, per evitare la creazione di un riferimento circolare tra le due classi. Per altre informazioni, vedere Riferimenti deboli.
Creare il renderer personalizzato in UWP
L'esempio di codice seguente illustra il renderer personalizzato per la piattaforma UWP:
[assembly: ExportRenderer(typeof(HybridWebView), typeof(HybridWebViewRenderer))]
namespace CustomRenderer.UWP
{
public class HybridWebViewRenderer : WebViewRenderer
{
const string JavaScriptFunction = "function invokeCSharpAction(data){window.external.notify(data);}";
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
Control.NavigationCompleted -= OnWebViewNavigationCompleted;
Control.ScriptNotify -= OnWebViewScriptNotify;
}
if (e.NewElement != null)
{
Control.NavigationCompleted += OnWebViewNavigationCompleted;
Control.ScriptNotify += OnWebViewScriptNotify;
Control.Source = new Uri($"ms-appx-web:///Content//{((HybridWebView)Element).Uri}");
}
}
async void OnWebViewNavigationCompleted(Windows.UI.Xaml.Controls.WebView sender, WebViewNavigationCompletedEventArgs args)
{
if (args.IsSuccess)
{
// Inject JS script
await Control.InvokeScriptAsync("eval", new[] { JavaScriptFunction });
}
}
void OnWebViewScriptNotify(object sender, NotifyEventArgs e)
{
((HybridWebView)Element).InvokeAction(e.Value);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
((HybridWebView)Element).Cleanup();
}
base.Dispose(disposing);
}
}
}
La classe HybridWebViewRenderer
carica la pagina Web specificata nella proprietà HybridWebView.Uri
in un controllo WebView
nativo e la funzione JavaScript invokeCSharpAction
viene inserita nella pagina Web, al termine del caricamento della pagina, con il metodo WebView.InvokeScriptAsync
. Dopo che l'utente immette il proprio nome e fa clic sull'elemento HTML button
, la funzione JavaScript invokeCSharpAction
viene eseguita, con il metodo OnWebViewScriptNotify
chiamato dopo che viene ricevuta una notifica dalla pagina Web. A sua volta, questo metodo richiama il metodo HybridWebView.InvokeAction
, che richiama l'azione registrata per visualizzare l'elemento popup.
Questa funzionalità si rende disponibile come indicato di seguito:
- A condizione che il renderer personalizzato sia associato a un nuovo Xamarin.Forms elemento:
- I gestori eventi per gli eventi
NavigationCompleted
eScriptNotify
sono registrati. L'eventoNavigationCompleted
viene attivato quando il controllo nativoWebView
ha completato il caricamento del contenuto corrente o se la navigazione ha avuto esito negativo. L'eventoScriptNotify
viene attivato quando il contenuto nel controllo nativoWebView
usa JavaScript per passare una stringa all'applicazione. La pagina Web genera l'eventoScriptNotify
chiamandowindow.external.notify
mentre passa un parametrostring
. - La proprietà
WebView.Source
viene impostata sull'URI del file HTML specificato dalla proprietàHybridWebView.Uri
. Il codice presuppone che il file sia archiviato nella cartellaContent
del progetto. Dopo che è stata visualizzata la pagina Web, viene attivato l'eventoNavigationCompleted
e viene richiamato il metodoOnWebViewNavigationCompleted
. La funzione JavaScriptinvokeCSharpAction
viene quindi inserita nella pagina Web con il metodoWebView.InvokeScriptAsync
, a condizione che la navigazione sia stata completata correttamente.
- I gestori eventi per gli eventi
- L'evento viene annullato quando l'elemento a cui è associato il renderer.
- L'elemento Xamarin.Forms viene pulito quando il renderer viene eliminato.