c#form的WebView2组件与窗体相互交互完整代码

我在此提供两个类可以直接完成他们的交互

using System.Windows.Forms;
using System;
using System.Runtime.InteropServices;
using Microsoft.Web.WebView2.WinForms;
using System.Threading.Tasks;
using Microsoft.Web.WebView2.Core;
using System.IO;
using System.Text;

    [ClassInterface(ClassInterfaceType.AutoDual)]
    [ComVisible(true)]
    public class AppBridgeBase
    {
        public WebView2 webView;
        protected string wn = "InternalWeb";
        protected string wf = "index.html";
        private AppBridge bridge;

        protected async void InitializeAsync(AppBridge bridge)
        {
            try
            {
                this.bridge = bridge;
                var env = await CoreWebView2Environment.CreateAsync(); //创建环境
                await bridge.webView.EnsureCoreWebView2Async(env);//等待WebView2初始化完成
                if (bridge.webView.CoreWebView2 == null)
                {
                    MessageBox.Show("CoreWebView2初始化失败");
                    return;
                }
                RegisterAppBridge();
                //加载本地内容
                string htmlPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, wn, wf);
                bridge.webView.CoreWebView2.Navigate(new Uri(htmlPath).AbsoluteUri);

            }
            catch (Exception err) { MessageBox.Show($"初始化错误: {err.Message}"); }
        }
        /// <summary>
        ///  注册桥接对象
        /// </summary>
        private void RegisterAppBridge()
        {
            try
            {
                if (bridge.webView.InvokeRequired)
                {
                    bridge.webView.Invoke((MethodInvoker)RegisterAppBridge);
                    return;
                }
                if (bridge.webView.CoreWebView2 != null)
                {
                    try
                    {
                        bridge.webView.CoreWebView2.RemoveHostObjectFromScript("bridge");
                    }
                    catch { }
                    // 注册新对象
                    bridge.webView.CoreWebView2.AddHostObjectToScript("bridge", bridge);
                    // 确认注册成功
                    //webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("alert(\"注册成功\");");
                    // 订阅 WebMessageReceived 事件
                    bridge.webView.CoreWebView2.WebMessageReceived += CoreWebView2_WebMessageReceived;
                }
            }
            catch (Exception err)
            {
                MessageBox.Show($"注册桥接对象失败: {err.Message}");
            }
        }
        private void CoreWebView2_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs e)
        {
            string message = e.TryGetWebMessageAsString();
            bridge.WebMessageReceived(message);
        }

        /// <summary>
        /// 发送信息通知
        /// </summary>
        public virtual async Task SendNotice(string info)
        {
            await webView.CoreWebView2.ExecuteScriptAsync("alert(\"来自客户端的消息:{\n" + info + "\n}\");");
        }
        /// <summary>
        /// c#调用web中的js函数
        /// </summary>
        public async Task RunWebFunctionAsync(string fun)
        {
            await webView.CoreWebView2.ExecuteScriptAsync(fun);
        }
        /// <summary>
        /// 接受来自网页的消息
        /// </summary>
        public virtual void WebMessageReceived(string message)
        {
            //MessageBox.Show($"接收Web消息: {message}");//监听功能,建议重载
        }
        /// <summary>
        /// 获取版本信息
        /// </summary>
        public virtual string GetAppInfo()
        {
            return $"应用程序信息\n产品名称: " + Application.ProductName + "\n版本: " + Application.ProductVersion + "";
        }
        /// <summary>
        /// web调用c#测试
        /// </summary>
        /// <param name="message">web传递的信息</param>
        public virtual void TestMessage(string message) { MessageBox.Show(message, "来自JavaScript的消息"); }
        /// <summary>
        /// c#测试调用web
        /// </summary>
        /// <param name="message">传递给web的信息</param>
        public virtual void TestSendMessage(string message) { RunWebFunctionAsync("test("+message+");"); }
        /// <summary>
        /// 创建默认路径默认网页模板
        /// </summary>
        public static AppBridge CreateTemplateTest(WebView2 web2)
        {
            Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory + "InternalWeb\\");
            string web = @"<!DOCTYPE html>"+"\n"+
"<html lang=" + '"' + "zh-CN" + '"' + ">\n" +
    "<head>\n" +
        "<meta charset=" + '"' + "UTF-8" + '"' + ">\n" +
        "<meta name=" + '"' + "viewport" + '"' + " content=" + '"' + "width=device-width, initial-scale=1.0" + '"' + ">\n" +
        "<title>模板</title>\n" +
        "<!-- <link rel=" + '"' + "stylesheet" + '"' + " href=" + '"' + "style.css" + '"' + "> -->\n" +
    "</head>\n" +
    "<body>\n" +
        "<!-- <script src=" + '"' + "script.js" + '"' + "></script> -->\n" +
        "<div id = 'butt' style = 'background-color: aquamarine;width: 100px height: 100px;' > 点击调用c#函数获取消息 </div>\n"+
            "<script>\n" +
        "document.getElementById('butt').addEventListener('click', async () => {\n" +
            "//window.chrome.webview.postMessage('按钮点击事件');\n//向c#发送消息(c#的监听(WebMessageReceived)功能可以接收此信息)\n" +
            "const info = await window.chrome.webview.hostObjects.bridge.GetAppInfo(); //如果c#函数没有返回值则不需要当成变量使用\n" +
            "document.getElementById('butt').innerText = info;\n" +
       " });\n" +
       "function test(a){ document.getElementById('butt').innerText = a; }"+
            "</script>\n" +
    "</body>\n" +
"</html>\n";
            if (!File.Exists(AppDomain.CurrentDomain.BaseDirectory + "InternalWeb\\index.html"))
            {
                File.WriteAllText(AppDomain.CurrentDomain.BaseDirectory + "InternalWeb\\index.html", web, Encoding.UTF8);
            }
            else
            {
                //提示作用
                MessageBox.Show(AppDomain.CurrentDomain.BaseDirectory + "InternalWeb\\index.html"+"该文件已存在,无法创建默认网页");
            }
            return new AppBridge(web2);
        }
    }
    [ClassInterface(ClassInterfaceType.AutoDual)]//必须
    [ComVisible(true)]//必须
    // 桥接类实现
    public class AppBridge:AppBridgeBase
    {
        /// <summary>
        /// 创建链接web的桥
        /// </summary>
        /// <param name="web">WebView2组件</param>
        /// <param name="webName">启动文件目录下的网页存放根目录</param>
        /// <param name="webFile">网页文件</param>
        public AppBridge(WebView2 web, string webName = "InternalWeb", string webFile = "index.html")
        {
            Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory + "InternalWeb\\");
            webView = web;
            wn = webName;
            wf = webFile;
            InitializeAsync(this);
        }

        /**********************下面则添加web需要调用与被调用的函数*************************/
        /// <summary>
        /// web调用的函数
        /// </summary>
        public string GetAppInfo()
        {
            return $"应用程序信息\n产品名称: " + Application.ProductName + "\n版本: " + Application.ProductVersion + "";
        }
        /// <summary>
        /// c#调用web函数
        /// </summary>
        /// <param name="message">js函数</param>
        public virtual void SendMessage(string message) { RunWebFunctionAsync("test(" + message + ");"); }
    }

用此方法创建即可使用

            bridge = AppBridge.CreateTemplateTest(webView);//代码中只带了相应的网页代码,或者自己创建,则可以AppBridge bridge =new AppBridge(webView);即可。

后续直接在AppBridge类里面添加web需要的功能函数。

### C# 中使用 WebView2 的案例 #### 创建并初始化 WebView2 控件 为了在 C# 应用程序中集成 WebView2,首先需要安装 Microsoft.Web.WebView2 NuGet 包。这可以通过 Visual Studio 或者命令行工具完成。 ```csharp using Microsoft.Web.WebView2.WinForms; using System.Windows.Forms; public class MainForm : Form { private WebView2 webView; public MainForm() { webView = new WebView2(); webView.Dock = DockStyle.Fill; Controls.Add(webView); InitializeAsync(); } async void InitializeAsync() { await webView.EnsureCoreWebView2Async(null); webView.CoreWebView2.Navigate("https://www.example.com"); } } ``` 此代码片段展示了如何创建 `WebView2` 实例,并将其设置为窗体的一部分[^2]。通过调用 `EnsureCoreWebView2Async()` 方法异步加载 WebView2 运行时环境,并导航到指定 URL 地址。 #### 处理 JavaScript 对话框和其他浏览器事件 当网页请求显示对话框或其他交互式提示时,可以利用 `WebMessageReceived` 事件监听器来接收来自页面的消息: ```csharp webView.CoreWebView2.Settings.AreDefaultScriptDialogsEnabled = false; webView.CoreWebView2.ScriptDialogOpening += (sender, args) => { MessageBox.Show(args.Message); args.Handled = true; }; ``` 上述配置禁用了默认脚本对话框,并自定义了一个消息框用于替代原生弹窗行为。 #### 加载本地 HTML 文件 如果希望加载位于应用程序资源中的静态HTML文件,则可通过以下方式实现路径转换访问权限授予: ```csharp string htmlFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "index.html"); // Grant file access permission to the folder containing index.html. await webView.CoreWebView2.Environment.SystemEnvironment.FileUtilities.GrantFileAccessToCurrentProcessAsync(htmlFilePath); webView.Source = new Uri($"file://{htmlFilePath}"); ``` 这段代码说明了怎样读取本地磁盘上的HTML文档作为初始页面源码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值