查看pdf时隐藏或修改Webview2的工具栏

问题描述

我正在使用新的 Webview2 控件在我的 WPF 应用程序中呈现 Pdf 文件

这运行良好,但我想自定义工具栏以隐藏例如某些条件下的保存按钮。我没有找到直接从 Webview2/CoreWebView2 对象执行此操作的方法属性

但是如果我检查在呈现 pdf 时生成的网页代码,我可以看到保存按钮所在的部分

enter image description here

是否可以在呈现之前拦截整个页面并更改 html ?我知道这样做很脏,因为它需要查找可能会更改的类 ID,但它现在可以作为临时解决方案使用。

解决方法

是的,可以 100% 地将脚本添加到您的环境中,以拦截和控制您正在渲染的内容。

我在 windows 窗体中使用 WebView2,所以我将向您展示我如何在桌面 windows 窗体应用程序中执行此操作,其他环境的过程类似,WPF 项目几乎相同。

步骤 1

设置并初始化 webview2 控件的默认设置

public FrmMainForm()
{
  InitializeComponent();

  // Resize/position client to a standard 720p HD TV and make room for tools
  var toolBarSize =
    PnlToolPanelTopRow.Height +
    PnlToolPanelLowerRow.Height;

  SetClientSizeCore(1280,toolBarSize + 720);
  //webview.Top = toolBarSize;
  webview.Height = 720;

  // Webview initialisation handler,called when control instatiated and ready
  webview.CoreWebView2InitializationCompleted += Webview_CoreWebView2InitializationCompleted;

  // Set defaults for tools
  TxtAppUrl.Text = "http://app/";
  TxtUserAgent.Text = DEFAULTUA;
}

注意“初始化处理程序”附加到初始化完成事件。

步骤 2

在您的初始化事件处理程序中,您需要在每次初始化浏览器视图时加载您希望运行的 JavaScript。这些脚本总是在加载页面中的任何脚本之前执行,或者在 dom 加载之前,它们在页面导航之后执行,因此您不能使用它们来控制导航周期。

这是一个例子,来自我的一个项目

private void Webview_CoreWebView2InitializationCompleted(object sender,CoreWebView2InitializationCompletedEventArgs e)
{
  // Custom URL handler (All URLS starting "http://app/" are intercepted directly by the application
  webview.CoreWebView2.AddWebResourceRequestedFilter("http://app/*",CoreWebView2WebResourceContext.All);
  webview.CoreWebView2.WebResourceRequested += WebResourceRequested;

  // Load in our custom JS API files to create the HbbTv JS environment
  webview.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(JsLoader.LoadApi("BrowserOverrides.js"));

  // Assign any back end C sharp classes to support our JS api's
  webview.CoreWebView2.AddHostObjectToScript("channelData",new ChannelData());

  // Event handler for notification of dom content load finished
  //webview.CoreWebView2.DOMContentLoaded += CoreWebView2_DOMContentLoaded;

  // Show dev tools by default
  webview.CoreWebView2.OpenDevToolsWindow();

  // Other misc settings
  webview.CoreWebView2.Settings.UserAgent = DEFAULTUA;

}

你也需要注意的那一行是:

webview.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(JsLoader.LoadApi("BrowserOverrides.js"));

我使用自定义加载器类,它从编译到我的应用程序的资源中获取我的 java 脚本文件,但是您不需要,传递给 AddScript 调用的唯一参数只是一个普通的 java 字符串脚本代码,例如:

webview.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("alert('hello world');");

将导致您的 webview2 会话在每次导航之后,但在页面中的 dom 和脚本加载和运行之前,对于在 webview 中浏览到的每个页面显示警报。

JS 代码可以完全访问浏览器环境,因此只需将常规 JS 处理程序附加到“dom 加载”或“页面加载”常规 java 脚本事件之一,然后使用标准 dom 操作来查找您想要的元素并将其显示样式设置为“无”。

步骤 3(可选)

您还可以从我的第二个代码片段中看到,您可以使用另外 2 个挂钩点。

webview.CoreWebView2.AddHostObjectToScript("channelData",new ChannelData());

将我的自定义 C# 类类型“ChannelData”添加到浏览器环境中,然后通过以下 JS 代码将其提供给浏览器

chrome.webview.hostObjects.channelData.(method name or property name accessible here)

在“hostObjects”之后的“channelData”名称与“AddHostObject”调用的第一个参数中使用的相同,第二个消息是一个常规的C#类,必须如下设置:

using HbbTvBrowser.DataClasses;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;

namespace JsSupportClasses
{
  [ClassInterface(ClassInterfaceType.AutoDual)]
  [ComVisible(true)]
  public class (Class Name Here)
  {
    public string SomeMethod()
    {
      return JsonConvert.SerializeObject(Some C# objects to return);
    }
  }
}

如果未提供类接口和 com 可见属性,则 Web 视图将无法看到该类,也无法调用该类。

任何由你的方法返回给 JS 代码的数据,必须是一个简单的数据类型,比如 int、bool 或 string,这意味着你不能返回复杂的对象,除非先序列化它们,然后再反序列化它们。 JS土地。

您会注意到还有一个 C# 级别的 dom 就绪处理程序。一旦加载了 HTML 并准备好访问,就会触发它,但在加载图像、脚本、css 或其他类似的东西之前。但是,您不能从 C# 更改 dom 内容,至少目前不能,我相信它可能会在今年某个时候出现在团队的视线中,但我无法确认。

虽然我自己不需要这样做,但我确实相信可以在 C# 中获得加载的 HTML 的副本,但这只是“副本”,更改它并不会改变实际加载 dom。