I'm trying to set WebView in auto size inside grid. But WebView content is not coming when I set <RowDefinition Height="Auto" />
// Written in Code Behind.
url = details.Url;
var browser = new WebView
{
Source = url,
};
grid.Children.Add(browser);
// Written in XAML Page.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid x:Name="grid" BackgroundColor="Red" />
</Grid>
Any help is appreciated. Thanks!
CodePudding user response:
I have done a sample and tested many times. I found the problem is the grid row and the webview both didn't have an exact value. So when the page shows, the height of the webview is 0.
So if you want to show the webview just with half screen, you can put all the controls in the same grid. Such as:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="AppTest.MainPage">
<Grid x:Name="grid" >
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<StackLayout Grid.Row="0">
<!-- some other controls-->
</StackLayout>
<WebView x:Name="webview" Grid.Row="1" BackgroundColor="DeepPink" Source=""/>
</Grid>
If you really want the webview have a fixed height for the content. You can use a custom renderer to do that. But this will delay the webview show time, because it need time to get the height of the content.
Declare the MyWebView class in the share project:
public class MyWebView : WebView { }
In the android part:
[assembly: Xamarin.Forms.ExportRenderer(typeof(MyWebView), typeof(MyWebViewRenderer))] namespace AppTest.Droid { public class MyWebViewRenderer : WebViewRenderer { public MyWebViewRenderer(Context context) : base(context) { } static MyWebView _xwebView = null; WebView _webView; class ExtendedWebViewClient : Android.Webkit.WebViewClient { public override async void OnPageFinished(WebView view, string url) { if (_xwebView != null) { int i = 10; while (view.ContentHeight == 0 && i-- > 0) // wait here till content is rendered await System.Threading.Tasks.Task.Delay(10); _xwebView.HeightRequest = view.ContentHeight; } base.OnPageFinished(view, url); } } protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e) { base.OnElementChanged(e); _xwebView = e.NewElement as MyWebView; _webView = Control; if (e.OldElement == null) { _webView.SetWebViewClient(new ExtendedWebViewClient()); } } } }
In the ios part:
[assembly: ExportRenderer (typeof(MyWebView), typeof(MyWebViewRenderer))] namespace AppTest.iOS { public class MyWebViewRenderer : WebViewRenderer { protected override void OnElementChanged(VisualElementChangedEventArgs e) { base.OnElementChanged(e); Delegate = new MyUIWebViewDelegate(this); } } }
MyUIWebViewDelegate.cs:
public class MyUIWebViewDelegate : UIWebViewDelegate
{
MyWebViewRenderer webViewRenderer;
public MyUIWebViewDelegate(MyWebViewRenderer _webViewRenderer = null)
{
webViewRenderer = _webViewRenderer ?? new MyWebViewRenderer();
}
public override async void LoadingFinished(UIWebView webView)
{
var wv = webViewRenderer.Element as MyWebView;
if (wv != null)
{
await System.Threading.Tasks.Task.Delay(10); // wait here till content is rendered
wv.HeightRequest = (double)webView.ScrollView.ContentSize.Height;
}
}
}
4: Use it in the xaml:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:AppTest"
x:Class="AppTest.MainPage">
<local:MyWebview x:Name="webview" Grid.Row="1" BackgroundColor="DeepPink" Source=""/>