Reputation: 166
I'm trying to get the height of a web page rendered in a Webview using a Custom Renderer. I've managed to hook into Load_Completed event which correctly fires when the page has fully rendered, but there doesn't seem to be anything exposing the content's height.
What can I use to get this?
Thanks in advance.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms.Platform.UWP;
using Xamarin.Forms;
using Windows.UI.Xaml.Navigation;
using Windows.UI.Xaml.Controls;
[assembly: ExportRenderer(typeof(Xamarin.Forms.WebView), typeof(ExtendedViewWebRenderer))]
namespace Project.UWP.CustomRenderers
{
public class ExtendedViewWebRenderer : WebViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.LoadCompleted += Load_Completed;
}
}
private void Load_Completed(object sender, Windows.UI.Xaml.Navigation.NavigationEventArgs e)
{
var _webView = (Windows.UI.Xaml.Controls.WebView)sender;
//Grab content's height here
}
}
}
Upvotes: 2
Views: 1936
Reputation: 2447
Here's where I landed. Know very little about UWP so please feel free to suggest improvements, but this seems to work fairly well. Note that in my case I'm passing an HTML string from my custom control to render/"navigate" to, if you're going to an actual page just use Control.Navigate(Uri source) instead.
public class ExtendedWebViewRenderer : ViewRenderer<ExtendedWebView, Windows.UI.Xaml.Controls.WebView>
{
protected override void OnElementChanged(ElementChangedEventArgs<ExtendedWebView> e)
{
try
{
base.OnElementChanged(e);
if (e.OldElement != null && Control != null)
{
Control.NavigationCompleted -= OnWebViewNavigationCompleted;
}
if (e.NewElement != null)
{
if (Control == null)
{
SetNativeControl(new Windows.UI.Xaml.Controls.WebView());
}
Control.NavigationCompleted += OnWebViewNavigationCompleted;
}
}
catch (Exception ex)
{
Console.WriteLine("Error at ExtendedWebViewRenderer OnElementChanged: " + ex.Message);
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
// update this based on your custom webview control and what you want it to do
if (Element is ExtendedWebView element && e.PropertyName.Equals(nameof(ExtendedWebView.Html)) && !string.IsNullOrWhiteSpace(element.Html))
Control.NavigateToString(element.Html);
}
private async void OnWebViewNavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
{
if (!args.IsSuccess)
return;
var heightString = await Control.InvokeScriptAsync("eval", new[] {"document.body.scrollHeight.toString()" });
if (int.TryParse(heightString, out int height))
{
Element.HeightRequest = height;
}
var widthString = await Control.InvokeScriptAsync("eval", new[] {"document.body.scrollWidth.toString()" });
if (int.TryParse(widthString, out int width))
{
Element.WidthRequest = width;
}
}
}
Upvotes: 2