• .NET MAUI中WebView的用法
  • 发布于 2个月前
  • 1038 热度
    0 评论
.NET 多平台应用 UI (.NET MAUI) WebView 在应用中显示远程网页、本地 HTML 文件和 HTML 字符串。 显示 WebView 的内容包括支持级联样式表 (CSS) 和 JavaScript。 默认情况下,.NET MAUI 项目包括 显示远程网页所需的 WebView 平台权限。

WebView 定义了以下属性:
Cookies类型 CookieContainer为 ,为 Cookie 集合提供存储。
CanGoBack类型 bool为 ,指示用户是否可以导航到以前的页面。 这是只读属性。
CanGoForward,类型 bool为 ,指示用户是否可以向前导航。 这是只读属性。

Source,类型 WebViewSource为 ,表示 显示的位置 WebView 。


这些属性由 BindableProperty 对象提供支持;也就是说,它们可以作为数据绑定的目标,并能进行样式设置。属性 Source 可以设置为 UrlWebViewSource 对象或对象,这两者 HtmlWebViewSource 都派生自 WebViewSource。 UrlWebViewSource用于加载使用 URL 指定的网页,而 HtmlWebViewSource 对象用于加载本地 HTML 文件或本地 HTML。

WebView 定义页面 Navigating 导航启动时引发的事件,以及 Navigated 页面导航完成时引发的事件。 WebNavigatingEventArgs事件附带Navigating的对象定义Cancel可用于取消导航的 类型的bool属性。 WebNavigatedEventArgs事件附带Navigated的对象定义Result指示导航结果的 类型的WebNavigationResult属性。

 重要提示:当 WebView 包含在 、 或 VerticalStackLayout中HorizontalStackLayout时,StackLayout必须指定其 HeightRequest 和 WidthRequest 属性。 如果未能指定这些属性, WebView 将不会呈现 。

显示网页
若要显示远程网页,请将 Source 属性设置为 string 指定 URI 的 :

XAML
<WebView Source="https://learn.microsoft.com/dotnet/maui" />
等效 C# 代码如下:
WebView webvView = new WebView
{
    Source = "https://learn.microsoft.com/dotnet/maui"
};
URI 必须使用指定的协议完全形成。

 备注:Source尽管 属性的类型为 WebViewSource,但属性可以设置为基于字符串的 URI。 这是因为 .NET MAUI 包含类型转换器和隐式转换运算符,用于将基于字符串的 URI 转换为 UrlWebViewSource 对象。

显示本地 HTML
若要显示内联 HTML,请将 Source 属性设置为 HtmlWebViewSource 对象:

XAML
<WebView>
    <WebView.Source>
        <HtmlWebViewSource Html="&lt;HTML&gt;&lt;BODY&gt;&lt;H1&gt;.NET MAUI&lt;/H1&gt;&lt;P&gt;Welcome to WebView.&lt;/P&gt;&lt;/BODY&gt;&lt;HTML&gt;" />
    </WebView.Source>
</WebView>
在 XAML 中,HTML 字符串可能因转义 < 和 > 符号而变得不可读。 因此,为了提高可读性,可以在节 CDATA 中内联 HTML:
XAML:
<WebView>
    <WebView.Source>
        <HtmlWebViewSource>
            <HtmlWebViewSource.Html>
                <![CDATA[
                <HTML>
                <BODY>
                <H1>.NET MAUI</H1>
                <P>Welcome to WebView.</P>
                </BODY>
                </HTML>
                ]]>
            </HtmlWebViewSource.Html>
        </HtmlWebViewSource>
    </WebView.Source>
</WebView>
等效 C# 代码如下:
WebView webView = new WebView
{
    Source = new HtmlWebViewSource
    {
       // 堆代码 duidaima.com
        Html = @"<HTML><BODY><H1>.NET MAUI</H1><P>Welcome to WebView.</P></BODY></HTML>"
    }
};

显示本地 HTML 文件
若要显示本地 HTML 文件,请将该文件添加到应用项目的 Resources\Raw 文件夹,并将其生成操作设置为 MauiAsset。 然后,可以从在设置为 Source 属性值的 对象中HtmlWebViewSource定义的内联 HTML 加载文件:

XAML:
<WebView>
    <WebView.Source>
        <HtmlWebViewSource>
            <HtmlWebViewSource.Html>
                <![CDATA[
                <html>
                <head>
                </head>
                <body>
                <h1>.NET MAUI</h1>
                <p>The CSS and image are loaded from local files!</p>
                <p><a href="localfile.html">next page</a></p>
                </body>
                </html>                    
                ]]>
            </HtmlWebViewSource.Html>
        </HtmlWebViewSource>
    </WebView.Source>
</WebView>
本地 HTML 文件可以加载级联样式表 (CSS) 、JavaScript 和图像(如果它们也已使用 MauiAsset 生成操作添加到应用项目中)。

重新加载内容
WebView 具有一个 Reload 可调用方法来重新加载其源:
WebView webView = new WebView();
...
webView.Reload();
执行导航
WebView支持使用 GoForward 方法进行GoBack编程导航。 这些方法支持在页面堆栈中WebView导航,并且仅应在检查 CanGoForward 属性的值CanGoBack后调用:
WebView webView = new WebView();
...

// Go backwards, if allowed.
if (webView.CanGoBack)
{
    webView.GoBack();
}

// Go forwards, if allowed.
if (webView.CanGoForward)
{
    webView.GoForward();
}
在 中 WebView以编程方式启动或由用户启动的页面导航时,会发生以下事件:
Navigating,在页面导航启动时引发。 WebNavigatingEventArgs事件附带Navigating的对象定义Cancel可用于取消导航的 类型的bool属性。

Navigated,在页面导航完成时引发。 WebNavigatedEventArgs事件附带Navigated的对象定义Result指示导航结果的 类型的WebNavigationResult属性。


处理 Android 上的权限
浏览到请求访问设备录制硬件(如相机或麦克风)的页面时,必须由控件授予 WebView 权限。 控件 WebView 使用 Android.Webkit.WebChromeClient Android 上的 类型来响应权限请求。 但是, WebChromeClient .NET MAUI 提供的实现会忽略权限请求。 必须创建继承自 MauiWebChromeClient 并批准权限请求的新类型。

从网页向 WebView 控件发出的权限请求不同于 .NET MAUI 应用对用户的权限请求。 用户针对整个应用请求和批准 .NET MAUI 应用权限。 该 WebView 控件依赖于应用访问硬件的能力。 为了说明此概念,请考虑一个网页,该网页请求访问设备的相机。 即使该请求已获得 WebView 控件的批准,但 .NET MAUI 应用尚未获得用户访问相机的批准,网页也无法访问该相机。

以下步骤演示如何截获来自 WebView 控件的权限请求以使用相机。 如果尝试使用麦克风,步骤将类似,只是使用麦克风相关权限而不是相机相关权限。

1.首先,将所需的应用权限添加到 Android 清单。 打开 “平台/Android/AndroidManifest.xml ”文件,并在节点中添加 manifest 以下内容:
<uses-permission android:name="android.permission.CAMERA" />
2.在应用中的某个时间点(例如加载包含 WebView 控件的页面时),请求用户授予权限以允许应用访问相机。
private async Task RequestCameraPermission()
{
    PermissionStatus status = await Permissions.CheckStatusAsync<Permissions.Camera>();

    if (status != PermissionStatus.Granted)
        await Permissions.RequestAsync<Permissions.Camera>();
}
3.将以下类添加到 “平台/Android ”文件夹,更改根命名空间以匹配项目的命名空间:
using Android.Webkit;
using Microsoft.Maui.Handlers;
using Microsoft.Maui.Platform;

namespace MauiAppWebViewHandlers.Platforms.Android;

internal class MyWebChromeClient: MauiWebChromeClient
{
    public MyWebChromeClient(IWebViewHandler handler) : base(handler)
    {

    }

    public override void OnPermissionRequest(PermissionRequest request)
    {
        // 堆代码 duidaima.com
        foreach (var resource in request.GetResources())
        {
            // Check if the web page is requesting permission to the camera
            if (resource.Equals(PermissionRequest.ResourceVideoCapture, StringComparison.OrdinalIgnoreCase))
            {
                // Get the status of the .NET MAUI app's access to the camera
                PermissionStatus status = Permissions.CheckStatusAsync<Permissions.Camera>().Result;

                // Deny the web page's request if the app's access to the camera is not "Granted"
                if (status != PermissionStatus.Granted)
                    request.Deny();
                else
                    request.Grant(request.GetResources());

                return;
            }
        }

        base.OnPermissionRequest(request);
    }
}
在前面的代码片段中 MyWebChromeClient , 类继承自 MauiWebChromeClient,并重写 OnPermissionRequest 方法以截获网页权限请求。 检查每个权限项以查看它是否与表示相机的 PermissionRequest.ResourceVideoCapture 字符串常量匹配。 如果相机权限匹配,代码将检查应用是否有权使用该相机。 如果具有权限,则会授予网页的请求。

4.SetWebChromeClient使用 Android WebView 控件上的 方法将 Chrome 客户端设置为 MyWebChromeClient。 以下两项演示了如何设置 Chrome 客户端:

.给定名为 theWebViewControl的 .NET MAUI WebView 控件,可以直接在平台视图(Android 控件)上设置 Chrome 客户端:
((IWebViewHandler)theWebViewControl.Handler).PlatformView.SetWebChromeClient(new MyWebChromeClient((IWebViewHandler)theWebViewControl.Handler));
.还可以使用处理程序属性映射来强制所有 WebView 控件使用 Chrome 客户端。 

当应用启动时(例如在 方法中MauiProgram.CreateMauiApp)时,应调用以下代码片段CustomizeWebViewHandler的 方法。
private static void CustomizeWebViewHandler()
{
#if ANDROID26_0_OR_GREATER
    Microsoft.Maui.Handlers.WebViewHandler.Mapper.ModifyMapping(
        nameof(Android.Webkit.WebView.WebChromeClient),
        (handler, view, args) => handler.PlatformView.SetWebChromeClient(new MyWebChromeClient(handler)));
#endif
}

设置 Cookie
可以在 上 WebView 设置 Cookie,以便它们随 Web 请求一起发送到指定的 URL。 通过将 对象添加到 Cookie 来 CookieContainer设置 Cookie,然后将容器设置为可绑定属性的值 WebView.Cookies 。 请参阅以下代码示例:
using System.Net;

CookieContainer cookieContainer = new CookieContainer();
Uri uri = new Uri("https://learn.microsoft.com/dotnet/maui", UriKind.RelativeOrAbsolute);

Cookie cookie = new Cookie
{
    Name = "DotNetMAUICookie",
    Expires = DateTime.Now.AddDays(1),
    Value = "My cookie",
    Domain = uri.Host,
    Path = "/"
};
cookieContainer.Add(uri, cookie);
webView.Cookies = cookieContainer;
webView.Source = new UrlWebViewSource { Url = uri.ToString() };
在此示例中,将一个 Cookie 添加到 CookieContainer 对象中,然后将该对象设置为 属性的值 WebView.Cookies 。 WebView当 将 Web 请求发送到指定的 URL 时,Cookie 随请求一起发送。

调用 JavaScript
WebView 包括从 C# 调用 JavaScript 函数并将任何结果返回到调用 C# 代码的功能。 此互操作是使用 EvaluateJavaScriptAsync 方法完成的,如以下示例所示:
Entry numberEntry = new Entry { Text = "5" };
Label resultLabel = new Label();
WebView webView = new WebView();
...

int number = int.Parse(numberEntry.Text);
string result = await webView.EvaluateJavaScriptAsync($"factorial({number})");
resultLabel.Text = $"Factorial of {number} is {result}.";
方法 WebView.EvaluateJavaScriptAsync 计算指定为 参数的 JavaScript,并将任何结果返回为 string。 在此示例中, factorial 调用 JavaScript 函数,该函数将返回 作为结果的 number 阶乘。 此 JavaScript 函数在 加载的本地 HTML 文件中 WebView 定义,并在以下示例中显示:
<html>
<body>
<script type="text/javascript">
function factorial(num) {
        if (num === 0 || num === 1)
            return 1;
        for (var i = num - 1; i >= 1; i--) {
            num *= i;
        }
        return num;
}
</script>
</body>
</html>

启动系统浏览器

可以使用 提供的 类Microsoft.Maui.Essentials在系统 Web 浏览器中Launcher打开 URI。 调用启动器 OpenAsync 的方法,并传入 string 表示要打开的 URI 的 或 Uri 参数:

await Launcher.OpenAsync("https://learn.microsoft.com/dotnet/maui");

用户评论