简体   繁体   中英

How do you modify platform specific properties from a Xamarin.Forms application?

I have a Xamarin.Forms Portable Application which contains a Page with a WebView control on it.

public class MainPage : ContentPage
{
    private WebView webView;

    public MainPage()
    {
        Content = (webView = new WebView());
    }
}

The WebView class is implemented differently on each platform -- each platform has it's own set of extra properties. For example on iOS, the WebView control is rendered as a UIWebView control , which has additional platform specific properties , some of which are not surfaced via the WebView class.

I would like to set some of those properties on a specific WebView control when my app is running on iOS. (Likewise, I'd like to do the equivalent for the Android, and UWP projects as well; as well as for other Xamarin.Forms controls that are not WebViews.)

So, how do you set the properties of those platform specific controls in Xamarin.Forms?

Posting an answer to help others, because I finally figured it out. -- It looks like you need to implement a Custom Renderer .

Essentially, in your device specific projects, you need to create a class that inherits the default renderer of a given control (there are some tables here .

Unfortunately, for more specific controls like WebView you will have to figure it out on your own.

Finally, you have to add an assembly attribute to "export" your renderer.

For example, the class in the iOS project might look like this:

using My.Project.iOS.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(WebView), typeof(CustomWebViewRenderer))]

namespace My.Project.iOS.Renderers
{
    internal class CustomWebViewRenderer : Xamarin.Forms.Platform.iOS.WebViewRenderer
    {
        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            var view = NativeView as UIKit.UIWebView;

            if (view != null)
            {    
                view.ScrollView.ScrollEnabled = false;
                view.ScrollView.Bounces = false;
            }
        }
    }
}

Note: that this renderer will be applied to ALL WebView controls rendered on iOS now. So if you want to only apply it to specific ones, you will need a way to signify to the custom renderer which ones to apply the additional settings to; the easiest way I've found to do this is with BindableProperty s (similar to DependencyProperty s in WPF).

To do this, you declare your BindableProperty somewhere in the shared PCL project like so:

namespace My.Project
{
    public static class Properties
    {
        public static readonly BindableProperty EnableScrollingProperty = BindableProperty.Create
        (
            "EnableScrolling",
            typeof(bool),
            typeof(WebView),
            true
        );
    }
}

And you can set it on your WebView object via:

webView.SetValue(My.Project.Properties.EnableScrollingProperty, false);

And the renderer's OnElementChanged method can be modified to get the value of that property and check it like so:

protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
    base.OnElementChanged(e);

    var enableScrolling = e?.NewElement?.GetValue(Properties.EnableScrollingProperty) as bool?;

    if (enableScrolling.HasValue)
    {
        var view = NativeView as UIKit.UIWebView;
        if (view != null)
        {
            view.ScrollView.ScrollEnabled = enableScrolling.Value;
            view.ScrollView.Bounces = enableScrolling.Value;
        }
    }
}

您要么需要创建一个自定义渲染器 ,要么使用Effects来设置平台特定的属性。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM