Пример #1
0
        public static int ContentHeight(this Android.Webkit.WebView webView)
        {
            MethodInfo method = webView.GetType().GetMethod("ComputeVerticalScrollRange", BindingFlags.NonPublic | BindingFlags.Instance);
            var        height = (int)method.Invoke(webView, new object[] { });

            return((int)(height / Display.Scale) + webView.MeasuredHeight);
        }
Пример #2
0
        public override async void OnPageFinished(Android.Webkit.WebView view, string url)
        {
            if (_reference == null || !_reference.TryGetTarget(out var renderer))
            {
                return;
            }
            if (renderer.Element == null || !renderer.Element.Navigating)
            {
                return;
            }

            renderer.Element.Navigating = false;

            renderer.Element.HandleNavigationCompleted(url);
            await renderer.OnJavascriptInjectionRequest(HybridWebViewControl.InjectedFunction);

            if (renderer.Element.EnableGlobalCallbacks)
            {
                foreach (var function in HybridWebViewControl.GlobalRegisteredCallbacks.ToList())
                {
                    await renderer.OnJavascriptInjectionRequest(HybridWebViewControl.GenerateFunctionScript(function.Key));
                }
            }

            foreach (var function in renderer.Element.LocalRegisteredCallbacks.ToList())
            {
                await renderer.OnJavascriptInjectionRequest(HybridWebViewControl.GenerateFunctionScript(function.Key));
            }

            renderer.Element.CanGoBack    = view.CanGoBack();
            renderer.Element.CanGoForward = view.CanGoForward();
            renderer.Element.HandleContentLoaded();
        }
Пример #3
0
        public async override void OnPageFinished(WebView view, string url)
        {
            try
            {
                _webView = view;
                if (_xwebView != null)
                {
                    view.Settings.JavaScriptEnabled = true;
                    await Task.Delay(100);

                    string result = await _xwebView.EvaluateJavaScriptAsync("(function(){return document.body.scrollHeight;})()");

                    _xwebView.HeightRequest = Convert.ToDouble(result);



                    MessagingCenter.Send <Object, PassModel>(this, "LoadFinished", new PassModel(_xwebView.Id, Convert.ToDouble(result)));
                }
                base.OnPageFinished(view, url);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"{ex.Message}");
            }
        }
            protected override void Dispose(bool disposing)
            {
                _webViewForms = null;
                _webViewDroid = null;

                base.Dispose(disposing);
            }
Пример #5
0
            public override bool ShouldOverrideUrlLoading(Android.Webkit.WebView webView, string url)
            {
                // If the URL is not our own custom scheme, just let the webView load the URL as usual
                var scheme = "hybrid:";

                if (!url.StartsWith(scheme))
                {
                    return(false);
                }

                // This handler will treat everything between the protocol and "?"
                // as the method name.  The querystring has all of the parameters.
                var resources  = url.Substring(scheme.Length).Split('?');
                var method     = resources[0];
                var parameters = System.Web.HttpUtility.ParseQueryString(resources[1]);

                if (method == "UpdateLabel")
                {
                    var textbox = parameters["textbox"];

                    // Add some text to our string here so that we know something
                    // happened on the native part of the round trip.
                    var prepended = string.Format("C# says \"{0}\"", textbox);

                    // Build some javascript using the C#-modified result
                    var js = string.Format("SetLabelText('{0}');", prepended);

                    webView.LoadUrl("javascript:" + js);
                }

                return(true);
            }
Пример #6
0
        public override void OnPageStarted(Android.Webkit.WebView view, string url, Bitmap favicon)
        {
            Element.SetValue(FormsWebView.SourceProperty, url);

            Element.InvokeEvent(WebViewEventType.NavigationComplete, new NavigationCompletedDelegate(Element, url, true));
            base.OnPageStarted(view, url, favicon);
        }
Пример #7
0
        public static Task <string> ExecuteScriptAsync(AWebView webview, string script)
        {
            var jsResult = new JavascriptResult();

            webview.EvaluateJavascript(script, jsResult);
            return(jsResult.JsResult);
        }
Пример #8
0
            public override bool ShouldOverrideUrlLoading(WebView webView, string url)
            {
                if (url.StartsWith("mailto:"))
                {
                    url = url.Replace("mailto:", "");

                    var mail = new Intent(Intent.ActionSend);
                    mail.SetType("application/octet-stream");
                    mail.PutExtra(Intent.ExtraEmail, new[] { url.Split('?')[0] });
                    webView.Context.StartActivity(mail);
                    return(true);
                }

                if (url.StartsWith("http:") || url.StartsWith("https:"))
                {
                    var link = new Intent(Intent.ActionView);
                    link.SetData(Uri.Parse(url));
                    webView.Context.StartActivity(link);
                    return(true);
                }

                if (url.StartsWith("tel:"))
                {
                    if (IsTelephonyEnabled)
                    {
                        var link = new Intent(Intent.ActionDial, Uri.Parse(url));
                        webView.Context.StartActivity(link);
                    }
                    return(true);
                }

                return(false);
            }
Пример #9
0
 public override void OnPageFinished(AWebView view, string url)
 {
     if (inner.TryGetTarget(out var target))
     {
         target.NotifyLoadComplete();
     }
 }
Пример #10
0
        private void ClearCookies()
        {
            var web = new Android.Webkit.WebView(MainActivity.Current);

            web.ClearCache(true);
            web.ClearHistory();
            web.Dispose();

#pragma warning disable 0618

            if (Build.VERSION.SdkInt >= BuildVersionCodes.LollipopMr1)
            {
                CookieManager.Instance.RemoveAllCookies(null);
                CookieManager.Instance.Flush();
            }
            else
            {
                var cookieSyncMngr = CookieSyncManager.CreateInstance(MainActivity.Current);
                cookieSyncMngr.StartSync();
                var cookieManager = CookieManager.Instance;
                cookieManager.RemoveAllCookie();
                cookieManager.RemoveSessionCookie();
                cookieSyncMngr.StopSync();
                cookieSyncMngr.Sync();
            }

#pragma warning restore 0618
        }
Пример #11
0
        public static int ContentWidth(this Android.Webkit.WebView webView)
        {
            MethodInfo method = webView.GetType().GetMethod("ComputeHorizontalScrollRange", BindingFlags.NonPublic | BindingFlags.Instance);
            var        width  = (int)method.Invoke(webView, new object[] { });

            return(width);
        }
Пример #12
0
        public void ToPng(TaskCompletionSource <ToFileResult> taskCompletionSource, string html, string fileName, int width)
        {
            //var size = new Size(8.5, 11);
            //var externalPath = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
            //using (var dir = new Java.IO.File(externalPath))
            //using (var file = new Java.IO.File(dir + "/" + fileName + ".png"))
            //{
            //    if (!dir.Exists())
            //        dir.Mkdir();
            //    if (file.Exists())
            //        file.Delete();

            var webView = new Android.Webkit.WebView(Android.App.Application.Context);

            webView.Settings.JavaScriptEnabled = true;
#pragma warning disable CS0618 // Type or member is obsolete
            webView.DrawingCacheEnabled = true;
#pragma warning restore CS0618 // Type or member is obsolete
            webView.SetLayerType(LayerType.Software, null);

            //webView.Layout(0, 0, (int)((size.Width - 0.5) * 72), (int)((size.Height - 0.5) * 72));
            webView.Layout(0, 0, width, width);

            webView.SetWebViewClient(new WebViewCallBack(taskCompletionSource, fileName, new PageSize {
                Width = width
            }, null, OnPageFinished));
            webView.LoadData(html, "text/html; charset=utf-8", "UTF-8");
            //}
        }
Пример #13
0
        bool AttemptToHandleCustomUrlScheme(Android.Webkit.WebView view, string url)
        {
            if (url.StartsWith("mailto"))
            {
                Android.Net.MailTo emailData = Android.Net.MailTo.Parse(url);

                Intent email = new Intent(Intent.ActionSendto);

                email.SetData(Android.Net.Uri.Parse("mailto:"));
                email.PutExtra(Intent.ExtraEmail, new String[] { emailData.To });
                email.PutExtra(Intent.ExtraSubject, emailData.Subject);
                email.PutExtra(Intent.ExtraCc, emailData.Cc);
                email.PutExtra(Intent.ExtraText, emailData.Body);

                if (email.ResolveActivity(Forms.Context.PackageManager) != null)
                {
                    Forms.Context.StartActivity(email);
                }

                return(true);
            }

            if (url.StartsWith("http"))
            {
                Intent webPage = new Intent(Intent.ActionView, Android.Net.Uri.Parse(url));
                if (webPage.ResolveActivity(Forms.Context.PackageManager) != null)
                {
                    Forms.Context.StartActivity(webPage);
                }

                return(true);
            }

            return(false);
        }
Пример #14
0
        public override WebResourceResponse ShouldInterceptRequest(Android.Webkit.WebView view, string url)
        {
            if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Lollipop)
            {
                goto EndShouldInterceptRequest;
            }

            if (Reference == null || !Reference.TryGetTarget(out FormsWebViewRenderer renderer))
            {
                goto EndShouldInterceptRequest;
            }
            if (renderer.Element == null)
            {
                goto EndShouldInterceptRequest;
            }

            var response = renderer.Element.HandleNavigationStartRequest(url);

            if (response.Cancel || response.OffloadOntoDevice)
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    if (response.OffloadOntoDevice)
                    {
                        AttemptToHandleCustomUrlScheme(view, url);
                    }

                    view.StopLoading();
                });
            }

EndShouldInterceptRequest:
            return(base.ShouldInterceptRequest(view, url));
        }
Пример #15
0
        public override bool ShouldOverrideUrlLoading(Android.Webkit.WebView view, IWebResourceRequest request)
        {
            if (Reference == null || !Reference.TryGetTarget(out FormsWebViewRenderer renderer))
            {
                goto EndShouldInterceptRequest;
            }
            if (renderer.Element == null)
            {
                goto EndShouldInterceptRequest;
            }

            string url      = request.Url.ToString();
            var    response = renderer.Element.HandleNavigationStartRequest(url);

            if (response.Cancel || response.OffloadOntoDevice)
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    if (response.OffloadOntoDevice)
                    {
                        AttemptToHandleCustomUrlScheme(view, url);
                    }

                    view.StopLoading();
                });
                return(true);
            }

EndShouldInterceptRequest:
            return(base.ShouldOverrideUrlLoading(view, request));
        }
Пример #16
0
        void CheckResponseValidity(Android.Webkit.WebView view, string url)
        {
            if (Reference == null || !Reference.TryGetTarget(out FormsWebViewRenderer renderer))
            {
                return;
            }
            if (renderer.Element == null)
            {
                return;
            }

            var response = renderer.Element.HandleNavigationStartRequest(url);

            if (response.Cancel || response.OffloadOntoDevice)
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    if (response.OffloadOntoDevice)
                    {
                        AttemptToHandleCustomUrlScheme(view, url);
                    }

                    view.StopLoading();
                });
            }
        }
Пример #17
0
        public override void OnPageFinished(WView view, string url)
        {
            if (_renderer?.Element == null || url == WebViewRenderer.AssetBaseUrl)
            {
                return;
            }

            var source = new UrlWebViewSource {
                Url = url
            };

            _renderer.IgnoreSourceChanges = true;
            _renderer.ElementController.SetValueFromRenderer(WebView.SourceProperty, source);
            _renderer.IgnoreSourceChanges = false;

            bool navigate = _navigationResult == WebNavigationResult.Failure ? !url.Equals(_lastUrlNavigatedCancel, StringComparison.OrdinalIgnoreCase) : true;

            _lastUrlNavigatedCancel = _navigationResult == WebNavigationResult.Cancel ? url : null;

            if (navigate)
            {
                var args = new WebNavigatedEventArgs(_renderer.GetCurrentWebNavigationEvent(), source, url, _navigationResult);
                _renderer.ElementController.SendNavigated(args);
            }

            _renderer.UpdateCanGoBackForward();

            base.OnPageFinished(view, url);
        }
 public override void OnPageFinished(WebView view, String url)
 {
     if (!view.Settings.LoadsImagesAutomatically)
     {
         view.Settings.LoadsImagesAutomatically = (true);
     }
 }
Пример #19
0
        /// <summary>
        /// Intercept request.
        /// </summary>
        /// <returns>The intercept request.</returns>
        /// <param name="view">View.</param>
        /// <param name="request">Request.</param>
        public override WebResourceResponse ShouldInterceptRequest(Android.Webkit.WebView view, IWebResourceRequest request)
        {
            string url  = request.Url.ToString();
            string ext  = MimeTypeMap.GetFileExtensionFromUrl(url);
            string mime = MimeTypeMap.Singleton.GetMimeTypeFromExtension(ext);

            if (url.ToLower().Contains("logoff"))
            {
                Xamarin.Forms.Device.BeginInvokeOnMainThread(App.Instance.Logout);
            }
            else if (request.Url.ToString().Contains("geofenceAutoCreate"))
            {
            }
            else if (mime != null)
            {
                HttpURLConnection conn = (HttpURLConnection) new URL(url).OpenConnection();
                foreach (var i in request.RequestHeaders)
                {
                    conn.SetRequestProperty(i.Key, i.Value);
                }
                var webResourceResponse = new WebResourceResponse(mime, "UTF-8", conn.InputStream);
                return(webResourceResponse);
            }

            BrowserPage.CheckWebSession();
            return(base.ShouldInterceptRequest(view, request));
        }
Пример #20
0
#pragma warning disable 0672, 618
            public override void OnReceivedError(Android.Webkit.WebView view, [GeneratedEnum] ClientError errorCode, string description, string failingUrl)
            {
                _webViewSuccess = false;
                _webErrorStatus = ConvertClientError(errorCode);

                base.OnReceivedError(view, errorCode, description, failingUrl);
            }
        public override bool ShouldOverrideUrlLoading(Android.Webkit.WebView view, string url)
        {
            if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.N)
            {
                return(base.ShouldOverrideUrlLoading(view, url));
            }

            if (Reference == null || !Reference.TryGetTarget(out FormsWebViewRenderer renderer))
            {
                return(base.ShouldOverrideUrlLoading(view, url));
            }
            if (renderer.Element == null)
            {
                return(base.ShouldOverrideUrlLoading(view, url));
            }

            var response = renderer.Element.HandleNavigationStartRequest(url);

            if (response.Cancel || response.OffloadOntoDevice)
            {
                if (response.OffloadOntoDevice)
                {
                    AttemptToHandleCustomUrlScheme(view, url);
                }
                view.StopLoading();
                return(true);
            }

            return(base.ShouldOverrideUrlLoading(view, url));
        }
Пример #22
0
            public override bool ShouldOverrideUrlLoading(Android.Webkit.WebView view, Android.Webkit.IWebResourceRequest request)
            {
                string url = request.Url.ToString();

                if (url.IsNullOrWhiteSpace())
                {
                    return(false);
                }

                if (url.StartsWith("url://") || url.StartsWith("http://") || url.StartsWith("https://") || url.StartsWith("ftp://"))
                {
                    return(base.ShouldOverrideUrlLoading(view, request));
                }

                try
                {
                    // Intent intent = new Intent(Intent.ACTION_VIEW, Android.Net.Uri.Parse(url)); // Java 源码
                    // intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // Java 源码

                    Intent intent = new Intent(Intent.ActionView, Android.Net.Uri.Parse(url));
                    intent.SetFlags(ActivityFlags.NewTask);

                    Android.App.Application.Context.StartActivity(intent);
                    return(true);
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.GetFullInfo());
                    System.Diagnostics.Debugger.Break();

                    // 防止crash (如果手机上没有安装处理某个scheme开头的url的APP, 会导致crash)
                    // 没有安装该app时,返回true,表示拦截自定义链接,但不跳转,避免弹出上面的错误页面
                    return(true);
                }
            }
Пример #23
0
        private void RunBlazorStartupScripts(AWebView view)
        {
            // TODO: we need to protect against double initialization because the
            // OnPageFinished event refires after the app is brought back from the
            // foreground and the webview is brought back into view, without it actually
            // getting reloaded.


            // Set up JS ports
            view.EvaluateJavascript(@"

        const channel = new MessageChannel();
        var nativeJsPortOne = channel.port1;
        var nativeJsPortTwo = channel.port2;
        window.addEventListener('message', function (event) {
            if (event.data != 'capturePort') {
                nativeJsPortOne.postMessage(event.data)
            }
            else if (event.data == 'capturePort') {
                if (event.ports[0] != null) {
                    nativeJsPortTwo = event.ports[0]
                }
            }
        }, false);

        nativeJsPortOne.addEventListener('message', function (event) {
        }, false);

        nativeJsPortTwo.addEventListener('message', function (event) {
            // data from native code to JS
            if (window.external.__callback) {
                window.external.__callback(event.data);
            }
        }, false);
        nativeJsPortOne.start();
        nativeJsPortTwo.start();

        window.external.sendMessage = function (message) {
            // data from JS to native code
            nativeJsPortTwo.postMessage(message);
        };

        window.external.receiveMessage = function (callback) {
            window.external.__callback = callback;
        }

        ", new JavaScriptValueCallback(() =>
            {
                // Set up Server ports
                _webViewHandler?.WebviewManager?.SetUpMessageChannel();

                // Start Blazor
                view.EvaluateJavascript(@"
                    Blazor.start();
                ", new JavaScriptValueCallback(() =>
                {
                    // Done; no more action required
                }));
            }));
        }
        public override void OnPageStarted(AWebView view, string url, Bitmap favicon)
        {
            if (view is null)
            {
                throw new ArgumentNullException(nameof(view));
            }

            if (_renderer?.Element == null || _webView == null || string.IsNullOrWhiteSpace(url) || url == WebViewRenderer.AssetBaseUrl)
            {
                return;
            }

            _renderer.SyncNativeCookiesToElement(url);
            var cancel = false;

            if (!url.Equals(_renderer.UrlCanceled, StringComparison.OrdinalIgnoreCase))
            {
                cancel = SendNavigatingCanceled(url);
            }

            _renderer.UrlCanceled = null;

            if (cancel)
            {
                _navigationResult = WebNavigationResult.Cancel;
                view.StopLoading();
            }
            else
            {
                _navigationResult = WebNavigationResult.Success;
                base.OnPageStarted(view, url, favicon);
                _webView.HandleNavigationStarting(new Uri(url));
            }
        }
Пример #25
0
        public void ToPdf(TaskCompletionSource <ToFileResult> taskCompletionSource, string html, string fileName, PageSize pageSize, PageMargin margin)
        {
            var externalPath = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;

            using (var dir = new Java.IO.File(externalPath))
                using (var file = new Java.IO.File(dir + "/" + fileName + ".pdf"))
                {
                    if (!dir.Exists())
                    {
                        dir.Mkdir();
                    }
                    if (file.Exists())
                    {
                        file.Delete();
                    }

                    var webView = new Android.Webkit.WebView(Android.App.Application.Context);
                    webView.Settings.JavaScriptEnabled = true;
#pragma warning disable CS0618 // Type or member is obsolete
                    webView.DrawingCacheEnabled = true;
#pragma warning restore CS0618 // Type or member is obsolete
                    webView.SetLayerType(LayerType.Software, null);

                    //webView.Layout(0, 0, (int)((size.Width - 0.5) * 72), (int)((size.Height - 0.5) * 72));
                    webView.Layout(0, 0, (int)System.Math.Ceiling(pageSize.Width), (int)System.Math.Ceiling(pageSize.Height));

                    webView.LoadData(html, "text/html; charset=utf-8", "UTF-8");
                    webView.SetWebViewClient(new WebViewCallBack(taskCompletionSource, fileName, pageSize, margin, OnPageFinished));
                }
        }
Пример #26
0
        async Task OnPageFinished(Android.Webkit.WebView webView, string fileName, PageSize pageSize, PageMargin margin, TaskCompletionSource <ToFileResult> taskCompletionSource)
        {
            if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Kitkat)
            {
                await Task.Delay(5);

                var builder = new PrintAttributes.Builder();
                //builder.SetMediaSize(PrintAttributes.MediaSize.NaLetter);
                builder.SetMediaSize(new PrintAttributes.MediaSize(pageSize.Name, pageSize.Name, (int)(pageSize.Width * 1000 / 72), (int)(pageSize.Height * 1000 / 72)));
                builder.SetResolution(new PrintAttributes.Resolution("pdf", "pdf", 72, 72));
                if (margin is null)
                {
                    builder.SetMinMargins(PrintAttributes.Margins.NoMargins);
                }
                else
                {
                    builder.SetMinMargins(new PrintAttributes.Margins((int)(margin.Left * 1000 / 72), (int)(margin.Top * 1000 / 72), (int)(margin.Right * 1000 / 72), (int)(margin.Bottom * 1000 / 72)));
                }
                var attributes = builder.Build();

                var adapter = webView.CreatePrintDocumentAdapter(Guid.NewGuid().ToString());

                var layoutResultCallback = new PdfLayoutResultCallback();
                layoutResultCallback.Adapter = adapter;
                layoutResultCallback.TaskCompletionSource = taskCompletionSource;
                layoutResultCallback.FileName             = fileName;
                adapter.OnLayout(null, attributes, null, layoutResultCallback, null);
            }
        }
Пример #27
0
        public void PrintHtml(string html)
        {
            var webview = new Android.Webkit.WebView(MainActivity.Instance);

            webview.SetWebViewClient(new PrintHTMLWebClient());
            webview.LoadDataWithBaseURL(null, html, "text/HTML", "UTF-8", null);
        }
Пример #28
0
        private void HandleDecisionHandlerDelegateResponse(Android.Webkit.WebView view, string url, Abstractions.Delegates.DecisionHandlerDelegate response)
        {
            if (!response.Cancel && !response.OffloadOntoDevice)
            {
                return;
            }

            var finishedManualResetEvent = new ManualResetEvent(false);

            void CancelOrOffloadOntoDevice()
            {
                if (response.OffloadOntoDevice && !AttemptToHandleCustomUrlScheme(view, url))
                {
                    Device.OpenUri(new Uri(url));
                }

                view.StopLoading();

                finishedManualResetEvent.Set();
            }

            if (Device.IsInvokeRequired)
            {
                Device.BeginInvokeOnMainThread(CancelOrOffloadOntoDevice);
            }
            else
            {
                CancelOrOffloadOntoDevice();
            }

            finishedManualResetEvent.WaitOne();
        }
Пример #29
0
            public override void OnPageFinished(Android.Webkit.WebView view, string url)
            {
                base.OnPageFinished(view, url);

                // 2020-11-01 20:13:44 解决XF中无法进入 Navigated 事件
                var source = new Xamarin.Forms.UrlWebViewSource {
                    Url = url
                };

                // 判断最近有没有 OnReceivedError, 若有异常则停止操作
                if (mReceiveError != null && mReceiveError.IsSameRequest(url) == true)
                {
                    // navigationResult = Xamarin.Forms.WebNavigationResult.Failure;
                    return;
                }
                else
                {
                    mReceiveError = null;
                }

                var args = new Xamarin.Forms.WebNavigatedEventArgs
                           (
                    Xamarin.Forms.WebNavigationEvent.NewPage,
                    source,
                    url,
                    Xamarin.Forms.WebNavigationResult.Success
                           );

                mRenderer.ElementController.SendNavigated(args);
            }
Пример #30
0
        /* For older versions of Android */
        public override bool ShouldOverrideUrlLoading(Android.Webkit.WebView View, string url)
        {
            if (System.Uri.TryCreate(url, System.UriKind.RelativeOrAbsolute, out System.Uri result))
            {
                if (ConfigSettings.ExternalExceptions.Any(url.Contains))
                {
                    Device.OpenUri(result);
                    return(true);
                }
            }
            var    pageInstance = ((AnnexioWebAppPage)App.Current.MainPage);
            string finalUrl     = pageInstance.AppendAppsflyerParam(url, MainActivity.AppsflyerUID);

            pageInstance.AddToHistory(finalUrl);

            if (pageInstance.IsHeaderRequired(url))
            {
                View.LoadUrl(finalUrl, customHeaders);
            }
            else
            {
                View.LoadUrl(finalUrl);
            }
            return(true);
        }
Пример #31
0
 public override void OnPageFinished(WebView view, string url)
 {
     base.OnPageFinished(view, url);
     ((IElementController)titleWebViewRenderer.Element).SetValueFromRenderer(TitledWebView.PageTitleProperty, view.Title);
 }