首页 > 解决方案 > 如何在 UWP 上的 Xamarin.Forms WebView 中启用 WebGL?

问题描述

我是 Xamarin.Forms 的新手,并尝试在我的带有 UWP 的 Windows 10 x64 v1803 机器上使用 WebView,但我看不到如何让它与 WebGL 一起使用。

使用 WebGL 的站点要么显示一条消息“您的视频卡不支持 WebGL,要么根本不显示图形内容。

这是 UWP 还是 WebView 本身的限制?

是 WebView 配置问题吗?

WebGL 适用于这台机器上的所有其他浏览器。

标签: windowswebviewxamarin.formsuwpwebgl

解决方案


我遇到了同样的问题,但是使用较新的 Xamarin Forms 需要更多的时间来解决这个问题。但是,我确实喜欢他们将本机 WebView 解析器移回 UWP/iOS/Android 项目(作为本机 XAML 对象)的职责,而不是在共享项目中使用带有编译器指令的代码分支。

首先在共享项目中创建一个 HybridWebView 类以用作您的 WebForm 视图对象:

public class HybridWebView : Xamarin.Forms.WebView
{
    Action<string> action;

    public static readonly BindableProperty UriProperty = BindableProperty.Create(
        propertyName: "Uri",
        returnType: typeof(string),
        declaringType: typeof(HybridWebView),
        defaultValue: default(string));

    public string Uri
    {
        get { return (string)GetValue(UriProperty); }
        set { SetValue(UriProperty, value); }
    }

    public void RegisterAction(Action<string> callback)
    {
        action = callback;
    }

    public void Cleanup()
    {
        action = null;
    }

    public void InvokeAction(string data)
    {
        if (action == null || data == null)        
        {
            return;
        }
        action.Invoke(data);
    }
}

然后在 UWP 项目中,创建一个自定义渲染器,它将构建原生 WebView 并将事件传递回 Shared 项目中的 WebForms 对象:

将其放在命名空间的顶部,以将 HybridWebView 与自定义渲染器链接:

[assembly: ExportRenderer(typeof(HybridWebView), typeof(WebViewRenderer2))]

然后创建渲染器类(对于 IOS 和 android 项目,如果你不考虑这个类,它默认为标准的原生控件,这对我来说似乎工作得很好):

public class WebViewRenderer2 : ViewRenderer<Xamarin.Forms.WebView, Windows.UI.Xaml.Controls.WebView>, IWebViewDelegate
    {
        Windows.UI.Xaml.Controls.WebView _control;

        public void LoadHtml(string html, string baseUrl)
        {

        }

        public void LoadUrl(string url)
        {

        }

        protected override void Dispose(bool disposing)
        {

        }

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
        {
            if (_control == null) {
                _control = new Windows.UI.Xaml.Controls.WebView(WebViewExecutionMode.SeparateProcess);
                SetNativeControl(_control);
            }
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            var xamWebView = sender as HybridWebView;
            switch(e.PropertyName.ToLower())
            {
                case "source":
                    var urlSource = xamWebView.Source as Xamarin.Forms.UrlWebViewSource;
                    _control.Source = new Uri(urlSource.Url);
                    break;
                case "width":
                    _control.Width = xamWebView.Width;
                    break;
                case "height":
                    _control.Height = xamWebView.Height;
                    break;
                case "isfocused":
                    var focused = xamWebView.IsFocused;
                    if (focused)
                        _control.Focus(FocusState.Programmatic);
                    else
                        _control.Focus(FocusState.Unfocused);
                    break;
            }
        }
    }

您还可以使用自定义渲染器来注入脚本,并且可以使用它从本机 webview 与 Xamarin 应用程序进行通信,如下所示:HybridWebView Communication


推荐阅读