如何在不使用Uno.UI的情况下从Xamarin.Forms应用程序调用JavaScript?

问题描述 投票:0回答:2

我有一个Xamarin.Forms应用程序,它通过Uno Platform投影到WASM。单击或点击后,我需要打开一个Web链接。我用以下方法解决它:

 try // Uwp & iOS & Android
            {
                await Browser.OpenAsync(new Uri("http://localhost"), BrowserLaunchMode.SystemPreferred); // Open url in-app browser for iOS & Android- native in UWP
            }
            catch (NotImplementedInReferenceAssemblyException ex) //Wasm falls here because lack of Xamarin.Essentials.
            {
                await DisplayAlert("Hata", "Not supported on WASM", "Anladım"); // Show the info about exception.



            }

对于Xamarin。 Android和iOS,以及UWP(Windows)。但是,Xamarin.Essentials尚不能在WASM上运行。因此,我需要调用Javascript并运行以下代码:

function openPage(x) {
    window.open(x);
}

我尝试将UNO.Foundation用于

WebAssemblyRuntime.InvokeJS("(function(){location.href=\"https://www.wikipedia.com/\";})();");

但是,它会干扰UWP UI类并破坏了我的项目。如何不使用UNO.Foundation类从Xamarin.Forms页面C#后端调用Javascript?谢谢。

c# xamarin xamarin.forms webassembly uno-platform
2个回答
1
投票

您可以使用混合Web视图,然后注入JavaScript代码来检测对此Web视图的每次点击https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/hybridwebview


0
投票

我通过Customizing via WebView解决了它:

[尝试创建将WebView扩展到允许从JavaScript调用C#代码。

WebView Renderer的过程:

创建HybridWebView自定义控件。从以下位置使用HybridWebViewXamarin.Forms。在以下位置为HybridWebView创建自定义渲染器每个平台。当用户单击HTML按钮时,JavaScript函数将调用C#Action。

1。创建HybridWebView

public class HybridWebView : 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);
    }
}

2。使用HybridWebView

<ContentPage
             xmlns:local="clr-namespace:CustomRenderer;assembly=CustomRenderer"
             x:Class="CustomRenderer.HybridWebViewPage"
             Padding="0,40,0,0">
    <local:HybridWebView x:Name="hybridWebView"
                         Uri="index.html" />
</ContentPage>

3。在UWP上创建自定义渲染器

[assembly: ExportRenderer(typeof(HybridWebView), typeof(HybridWebViewRenderer))]
namespace CustomRenderer.UWP
{
    public class HybridWebViewRenderer : WebViewRenderer
    {
        const string JavaScriptFunction = "function invokeCSharpAction(data){window.external.notify(data);}";

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null)
            {
                Control.NavigationCompleted -= OnWebViewNavigationCompleted;
                Control.ScriptNotify -= OnWebViewScriptNotify;
            }
            if (e.NewElement != null)
            {
                Control.NavigationCompleted += OnWebViewNavigationCompleted;
                Control.ScriptNotify += OnWebViewScriptNotify;
                Control.Source = new Uri($"ms-appx-web:///Content//{((HybridWebView)Element).Uri}");
            }
        }

        async void OnWebViewNavigationCompleted(Windows.UI.Xaml.Controls.WebView sender, WebViewNavigationCompletedEventArgs args)
        {
            if (args.IsSuccess)
            {
                // Inject JS script
                await Control.InvokeScriptAsync("eval", new[] { JavaScriptFunction });
            }
        }

        void OnWebViewScriptNotify(object sender, NotifyEventArgs e)
        {
            ((HybridWebView)Element).InvokeAction(e.Value);
        }
    }
}

最后,从代码中调用函数:

  hybridWebView.RegisterAction(data => Browser.OpenAsync(data, BrowserLaunchMode.SystemPreferred));
                hybridWebView.InvokeAction("http://localhost");
© www.soinside.com 2019 - 2024. All rights reserved.