Skip to content

Instantly share code, notes, and snippets.

@Ouadie
Last active December 22, 2015 17:53
Show Gist options
  • Save Ouadie/78fc85965ebaf49e06d4 to your computer and use it in GitHub Desktop.
Save Ouadie/78fc85965ebaf49e06d4 to your computer and use it in GitHub Desktop.
Scrollable Webview with auto-height for WinRT

AdaptativeWebView

Scrollable Webview with auto-height for WinRT

Installation

  • Add the files (.cs and .xaml) to your existing solution.

License

MIT

<UserControl x:Class="UserControls.WebView.AdaptativeWebView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400"
x:Name="Self">
<Grid Background="{Binding Background, ElementName=Self}">
<ScrollViewer>
<Grid Height="Auto">
<WebView x:Name="WebviewContent"
VerticalAlignment="Top"
DefaultBackgroundColor="Transparent" />
<Rectangle Height="{Binding Height, ElementName=WebviewContent}"
Name="RecWeb"
VerticalAlignment="Top"
Fill="#00000000"
Tapped="RecWebTapped" />
</Grid>
</ScrollViewer>
</Grid>
</UserControl>
namespace UserControls.WebView
{
using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
public sealed partial class AdaptativeWebView : UserControl
{
#region Static Fields
// Using a DependencyProperty as the backing store for WebView. This enables animation, styling, binding, etc...
public static readonly DependencyProperty WebViewProperty =
DependencyProperty.Register("WebView", typeof(WebView), typeof(AdaptativeWebView), new PropertyMetadata(null));
#endregion
#region Constructors and Destructors
public AdaptativeWebView()
{
this.InitializeComponent();
this.WebView = this.WebviewContent;
this.WebviewContent.ScriptNotify += this.WebviewContentScriptNotify;
}
#endregion
#region Public Properties
public WebView WebView
{
get
{
return (WebView)this.GetValue(WebViewProperty);
}
set
{
this.SetValue(WebViewProperty, value);
}
}
#endregion
#region Public Methods and Operators
public void NavigateToContent(string html, string styles = "", string scripts = "", int padding = 10)
{
this.WebviewContent.NavigateToString(GenerateHtml(html, styles, scripts, padding));
}
#endregion
#region Methods
private static string GenerateHtml(string html, string styles, string scripts, int padding)
{
return @"<html>
<head>
<meta name=""viewport"" content=""width=device-width, initial-scale=1, user-scalable=no"" />
<script type=""text/javascript"">
document.addEventListener('click', function(e) {
e = e || window.event;
var target = e.target || e.srcElement;
if(target.nodeName === 'A'){
target.className += ' font-bold';
setTimeout(function() {target.className -= ' font-bold'; }, 200);
}
}, false);
function loadLink(x,y){
var el = document.elementFromPoint(x, y);
el && el.click();
};
function getDocHeight(id) {
var D = document;
return Math.max(
Math.max(document.getElementById(id).scrollHeight, document.getElementById(id).scrollHeight),
Math.max(document.getElementById(id).offsetHeight, document.getElementById(id).offsetHeight),
Math.max(document.getElementById(id).clientHeight, document.getElementById(id).clientHeight)
);
};
function notifyDocumentHeightChanged(id){
window.external.notify('rendered_height='+getDocHeight(id));
};
</script>
<style>
body { padding: " + padding + @"px; }
.font-bold { text-decoration: underline; }
a:active { text-decoration: underline;}
</style>
" + styles + @"
" + scripts + @"
</head>
<body onload='notifyDocumentHeightChanged(""maincontent"")' onresize='notifyDocumentHeightChanged(""maincontent"")'>
<div id='maincontent'>" + html + @"</div>
</body>
</html>";
}
private async void RecWebTapped(object sender, TappedRoutedEventArgs e)
{
var p = e.GetPosition(this.WebviewContent);
var x = Convert.ToInt32(p.X);
var y = Convert.ToInt32(p.Y);
string[] size =
{
x.ToString(),
y.ToString()
};
await this.WebviewContent.InvokeScriptAsync("loadLink", size);
}
private void WebviewContentScriptNotify(object sender, NotifyEventArgs e)
{
if (e.Value.Contains("rendered_height"))
{
var valuePair = e.Value.Split('=');
if (valuePair != null && valuePair[0] == "rendered_height")
{
var renderedHeight = double.Parse(valuePair[1]) + 20;
this.WebviewContent.Height = renderedHeight;
}
}
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment