WPF+WebView2+react/vue/angular

创建WPF项目

安装WbeView2 Nuget包

在窗体中添加命名空间

xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"

使用控件

<wv2:WebView2 x:Name="webview"/>

在MainWindow中初始化

        public MainWindow()
        {
            InitializeComponent();
            this.Closing += MainWindow_Closing;
            InitializeAsync();
            webView.NavigationStarting += WebView_NavigationStarting;

        }

        private void WebView_NavigationStarting(object sender, CoreWebView2NavigationStartingEventArgs e)
        {
            //声明一个对象,暴露给js使用
            var frame = new Frame();
            webView.CoreWebView2.AddHostObjectToScript("frame", frame);
        }

        async void InitializeAsync()
        {
            //显示初始化CoreWebView2
            await webView.EnsureCoreWebView2Async();
            打开开发工具
            //webView.CoreWebView2.OpenDevToolsWindow();

            //虚拟映射
            webView.CoreWebView2.SetVirtualHostNameToFolderMapping("html.sample", "./dist", CoreWebView2HostResourceAccessKind.Deny);
            //导航
            webView.CoreWebView2.Navigate("https://html.sample/index.html");
        }

        private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            webView.Dispose();
        }

Frame的实现为:

        /// <summary>
     /// 提供给web页面的api
     /// </summary>
    [System.Runtime.InteropServices.ComVisible(true)]//必须加,不然AddHostObjectToScript报异常
    public class Frame
    {
        public void Show()
        {
            MessageBox.Show("hello React Native");
        }
        /*
         * How to use of Javascript?
          var win = (window as any).chrome.webview.hostObjects.frame;//get native object
          const sub = async (a: any, b: any) => { return await win.Add(a, b) };//return Promise object
          sub(10,2).then((res)=>alert(res));
         * */
        public int Add(int a, int b)
        {
            return a + b;
        }
    }

 主程序与页面之间的通讯

相较于上述所提的通过JS实现WebView2宿主程序和前端页面进行通信的方法,在WebView2中,更加通用而高效的方式是WebMessage,它是一个异步的消息通信,并且支持双向通信。

  • WebView2 控件中的 Web 内容可以使用 window.chrome.webview.postMessage 向宿主程序发布消息。宿主程序使用任何注册到 WebMessageReceived 委托方法处理消息。
  • 主程序使用 CoreWebView2.PostWebMessageAsString 或 CoreWebView2.PostWebMessageAsJSON 将消息发布到 WebView2 控件中的 Web 内容。这些消息由添加到 window.chrome.webview.addEventListener 的处理程序捕获。

前端页面发送消息给宿主程序:

在WebView中定义接收到消息的处理函数:

webView.WebMessageReceived += (s, e) =>
{
    MessageBox.Show(e.WebMessageAsJson);
};

在前端脚本中发送消息:

(windows as any).chrome.webview.postMessage('hello world');

主程序发消息给前端页面:

在前端脚本中需注册消息的处理函数:

(windows as any).chrome.webview.addEventListener('message', event => alert(event.data));

在主程序有两个方法可以进行发送,分别是PostWebMessageAsJson()PostWebMessageAsString()

webView.CoreWebView2.PostWebMessageAsString("hello world");

禁用WebMessage:

如果为了安全起见,也可以通过设置将其禁用:

webView.CoreWebView2.Settings.IsWebMessageEnabled = false;

在这里我们可以实现页面加载完成之后的回调操作

window.onload = function () {
  (windows as any).chrome.webview.postMessage("chaet page loaded complete!");
};
//接收注册消息
webView.WebMessageReceived += WebLoaded;

public void WebLoaded(object? obj, CoreWebView2WebMessageReceivedEventArgs e)
{
    MessageBox.Show(e.WebMessageAsJson);
}

Dev Protocol

  • 使用websocket的方式来驱动
var env = await CoreWebView2Environment.CreateAsync(options:new CoreWebView2EnvironmentOptions("--remote-debugging-port=9222"));
await webView.EnsureCoreWebView2Async(env);
  • 使用CoreWebView2内置方法
    1. 执行命令:CoreWebView2.CallDevToolsProtocolMethodAsync
    2. 注册回调:CoreWebView2.GetDevToolsProtocolEventReceiver
await webView.CoreWebView2.CallDevToolsProtocolMethodAsync("Network.enable", "{}");
var eventRecieiver = webView.CoreWebView2.GetDevToolsProtocolEventReceiver("Network.requestWillBeSent");
eventRecieiver.DevToolsProtocolEventReceived += (s, e) =>
{
    Console.WriteLine(e.ParameterObjectAsJson + "\n");
};

关于CallDevToolsProtocolMethodAsync (string methodName, string parametersAsJson)方法方法描述:

methodName:The full name of the method in the format {domain}.{method}
parametersAsJson:A JSON formatted string containing the parameters for the corresponding method.

💡 chromedevtools的操作命名空间与相关方法文档:domain

### WPF中使用WebView2Vue.js集成 为了在WPF应用程序中成功集成了Vue.js前端框架,需要按照特定流程设置环境和编写代码。首先,在开发环境中安装WebView2 Runtime是必要的前置条件[^1]。 #### 创建WPF项目并配置WebView2控件 创建一个新的WPF项目之后,需向项目的XAML文件添加WebView2控件的支持命名空间: ```xml <Window x:Class="YourNamespace.MainWindow" ... xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"> <Grid> <!-- WebView2 控件 --> <wv2:WebView2 Name="webView"/> </Grid> </Window> ``` 此部分定义了用于显示Web内容的区域,并允许后续加载由Vue驱动的应用程序界面[^4]。 #### 配置Vue应用并与C#交互 为了让Vue应用能够运行于WebView2容器内,通常做法是在本地服务器环境下启动该应用或将编译后的静态资源部署至可访问路径下。接着通过`Source`属性指定要加载的目标URL给WebView2实例。 对于希望实现的功能——即从Vue端触发动作来改变背景颜色为例,则可以在Vue组件内部这样处理事件响应逻辑: ```html <template> <div> <button @click="changeBackgroundColor">Change Background Color</button> </div> </template> <script> export default { methods: { async changeBackgroundColor() { await window.chrome.webview.hostObjects.CSharp.SetBackgroundColor('#FF0000'); } } } </script> ``` 上述代码片段展示了如何利用JavaScript桥接机制让Vue中的方法可以直接调用宿主进程里的.NET成员函数[^2]。 最后一步涉及到了后台服务层面上的工作,也就是确保存在相应的C#接口供前端调用。这可以通过注册对象和服务提供者完成初始化过程的一部分,从而建立起完整的双向通信链路。 ```csharp using Microsoft.Web.WebView2.Core; // ... public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); webView.NavigationCompleted += (sender, args) => { var cSharpObject = new CSharpHostObject(webView); webView.CoreWebView2.PostAsync("registerHostObject", JsonSerializer.Serialize(cSharpObject)); }; } private class CSharpHostObject { private readonly WebView2 _webview; public CSharpHostObject(WebView2 webview) { _webview = webview; } public void SetBackgroundColor(string color) { Dispatcher.Invoke(() => this._webview.Background = Brushes.Red); // 这里简化为固定红色 } } } ``` 这段C#代码实现了当导航完成后自动注册一个可供JS侧调用的对象实例;而`SetBackgroundColor`方法则负责实际修改窗口背景的任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值