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:

Relazione tra la classe WebView e le relative classi native di implementazione

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:

  1. Creare il controllo personalizzato HybridWebView.
  2. Utilizzare da HybridWebViewXamarin.Forms.
  3. 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 elemento Action 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'elemento Action registrato.
  • Un metodo InvokeAction che richiama l'elemento Action 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:

  1. Creare una sottoclasse della WkWebViewRenderer classe in iOS e la WebViewRenderer classe in Android e UWP, che esegue il rendering del controllo personalizzato.
  2. Eseguire l'override del metodo che esegue il OnElementChanged rendering della WebView logica e scrivere per personalizzarla. Questo metodo viene chiamato quando viene creato un HybridWebView oggetto .
  3. 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:

Responsabilità del progetto di renderer personalizzato HybridWebView

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:

HybridWebView in ogni piattaforma

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 JavaScript invokeCSCode, con il valore dell'elemento input passato alla funzione.
  • La funzione invokeCSCode chiama la funzione log per visualizzare i dati inviati all'elemento Action di C#. Chiama quindi il metodo invokeCSharpAction per richiamare l'elemento Action di C#, passando il parametro ricevuto dall'elemento input.

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 funzione invokeCSCode, che a sua volta richiama la funzione invokeCSharpAction.
  • La funzione invokeCSharpAction richiama un metodo nel renderer personalizzato, che a sua volta richiama il metodo HybridWebView.InvokeAction.
  • Il metodo HybridWebView.InvokeAction richiama l'elemento Action 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 relativo WKUserContentController oggetto. L'oggetto WkUserContentController consente la pubblicazione di messaggi e l'inserimento di script utente in una pagina Web.
  • Il costruttore renderer crea un WKUserScript oggetto che inserisce la invokeCSharpAction funzione JavaScript nella pagina Web dopo il caricamento della pagina Web.
  • Il costruttore renderer chiama il WKUserContentController.AddUserScript metodo per aggiungere l'oggetto WKUserScript al controller del contenuto.
  • Il costruttore renderer chiama il WKUserContentController.AddScriptMessageHandler metodo per aggiungere un gestore di messaggi di script denominato invokeAction all'oggetto WKUserContentController , che causerà la definizione della funzione window.webkit.messageHandlers.invokeAction.postMessage(data) JavaScript in tutti i frame in tutte le WebView istanze che usano l'oggetto WKUserContentController .
  • 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 cartella Content del progetto. Quando viene visualizzata la pagina Web, la funzione JavaScript invokeCSharpAction viene inserita nella pagina Web.
  • 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 nuovo JavascriptWebViewClient oggetto come implementazione di WebViewClient.
    • Il metodo WebView.AddJavascriptInterface inserisce una nuova istanza di JSBridge nel frame principale del contesto JavaScript di WebView, denominandola jsBridge. In questo modo è possibile accedere ai metodi presenti nella classe JSBridge da JavaScript.
    • Il metodo WebView.LoadUrl carica il file HTML specificato dalla proprietà HybridWebView.Uri. Il codice specifica che il file è archiviato nella cartella Content del progetto.
    • Nella classe JavascriptWebViewClient la funzione JavaScript invokeCSharpAction viene inserita nella pagina Web al termine del caricamento della pagina.
  • 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.Exportoppure 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 e ScriptNotify sono registrati. L'evento NavigationCompleted viene attivato quando il controllo nativo WebView ha completato il caricamento del contenuto corrente o se la navigazione ha avuto esito negativo. L'evento ScriptNotify viene attivato quando il contenuto nel controllo nativo WebView usa JavaScript per passare una stringa all'applicazione. La pagina Web genera l'evento ScriptNotify chiamando window.external.notify mentre passa un parametro string.
    • 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 cartella Content del progetto. Dopo che è stata visualizzata la pagina Web, viene attivato l'evento NavigationCompleted e viene richiamato il metodo OnWebViewNavigationCompleted. La funzione JavaScript invokeCSharpAction viene quindi inserita nella pagina Web con il metodo WebView.InvokeScriptAsync, a condizione che la navigazione sia stata completata correttamente.
  • L'evento viene annullato quando l'elemento a cui è associato il renderer.
  • L'elemento Xamarin.Forms viene pulito quando il renderer viene eliminato.