WebView2UI - 在WPF之中使用WebView2的一些经验总结

news/2024/9/24 18:03:46

项目地址:https://github.com/skyw18/skyw18-WebView2UI
webview简介与生命周期:WPF 应用中的 WebView2 入门 - Microsoft Edge Developer documentation | Microsoft Learn

具体代码可以参考微软官方示例文档 WPF 示例应用 - Microsoft Edge Developer documentation | Microsoft Learn

使用方法:

使用nuget添加Microsoft.Web.WebView2,将Resource目录下的app子目录复制到生成的可执行文件同一目录,xaml之中插入 xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"

如果需要使用webview2 prerelease版,需要在NuGet管理界面进入项目网页,然后在下面的Package Manager之中复制命令行到程序包管理控制台,在上面的下拉菜单之中选择要安装的项目,然后运行命令即可。

初始化Webview2和几种加载html的方式

public MainWindow()
{InitializeComponent();InitializeAsync();
}async void InitializeAsync()
{//加载之前需等待webview2 initialized完成。await webView.EnsureCoreWebView2Async(null);//webview2加载资源的几种方式,也可以在XAML里设定source,可以使用1,2两种方法//1. 直接通过URL加载网络页面//webView.Source = new Uri("https://localhost:44380");//2. 通过路径加载本地页面webView.Source = new Uri("file:///" + System.Environment.CurrentDirectory + "\\app\\index.html");//3. 将本地路径设为虚拟域名,通过虚拟域名加载本地页面//请注意,SetVirtualHostNameToFolderMapping这个方法需等待webview初始化完成,否则会因webview为空而崩溃,//所以不能放在MainWindow之中同步执行,会卡死,也不能放在wvMain.CoreWebView2InitializationCompleted和NavigationCompleted之中执行,//因为这两个方法都是加载完页面之后才会触发,如果xaml之中source为空,则永不会被执行,所以需在MainWindow异步执行并通过EnsureCoreWebView2Async方法等待://webView.CoreWebView2.SetVirtualHostNameToFolderMapping("appassets.example", "app", CoreWebView2HostResourceAccessKind.Allow);//webView.Source = new Uri("https://appassets.example/hello.html");//4. 直接加载html字符串  加载的字符串大小不能大于2m //html之中资源的链接必须通过虚拟域名,资源放在跟执行程序同一个目录下也无法直接调用//string htmlContent = @"<img src='http://appassets.example/bg0.jpg'>";//string htmlContent = @"<h1>hello, world!</h1>";//webView.NavigateToString(htmlContent);         
}

开发混合应用时用到的一些功能

async void InitializeAsync()
{//..... 初始化代码,省略,参考上面//webview2控件设定透明度        //webView.DefaultBackgroundColor = System.Drawing.Color.Transparent;//下面这行语句可以禁用f5等快捷键 以阻止用户误触f5刷新页面webView.CoreWebView2.Settings.AreBrowserAcceleratorKeysEnabled = false;//禁止缩放界面比例webView.CoreWebView2.Settings.IsZoomControlEnabled = false;webView.NavigationCompleted += webView_NavigationCompleted;//webView.CoreWebView2InitializationCompleted += webView_InitializationCompleted;//webView.NavigationStarting += EnsureHttps;//webView.NavigationCompleted += CancelRightButton;webView.WebMessageReceived += WebView_WebMessageReceived; 
}async void webView_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs args)
{//一些使用js实现的功能//禁止鼠标右键菜单await webView.CoreWebView2.ExecuteScriptAsync("window.addEventListener('contextmenu', window => {window.preventDefault();});");//禁止鼠标左键拖动选择await webView.CoreWebView2.ExecuteScriptAsync("window.addEventListener('selectstart', window => {window.preventDefault();});");//禁止拖动文件到窗口await webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("window.addEventListener('dragover',function(e){e.preventDefault();},false);" +"window.addEventListener('drop',function(e){" +"e.preventDefault();" +"console.log(e.dataTransfer);" +"console.log(e.dataTransfer.files[0])" +"}, false);");//await webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("window.chrome.webview.postMessage(window.document.URL);");//await webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("window.chrome.webview.addEventListener(\'message\', event => alert(event.data));");//await webView.CoreWebView2.ExecuteScriptAsync($"alert('alertt');document.getElementById('hello').innerHTML='hello;");
}

C#在html之中插入脚本

await wView.CoreWebView2.ExecuteScriptAsync("some_func();");  //执行JS
var result = await webView.CoreWebView2.ExecuteScriptWithResultAsync("get_json();"); //执行带返回值的JS
string scriptResult = await _webViewFrames[iframeNumber].ExecuteScriptAsync(dialog.Input.Text);  //插入 iFrame

若html内容如下:

var user_id = 120; //数字
var user_name = "hello"; //字符串
var user_info = {name: "hello",age: 12}; //json串
function get_user_name() {return user_name;}
function get_user_id() {return user_id;}
function get_user_info() {return user_info;}

使用SimpleJSON对返回数据进行处理:

var result_user_id = await webView.CoreWebView2.ExecuteScriptWithResultAsync("user_id");
//等效于 var result_user_id = await webView.CoreWebView2.ExecuteScriptWithResultAsync("get_user_id()");
long user_id = JSON.Parse(result_user_id.ResultAsJson).AsLong;//处理数值
//如果数值过大则会自动加双引号此时需long.TryParse(result.ResultAsJson.Replace("\"", ""), out t);//处理字符串
var result_user_name = await webView.CoreWebView2.ExecuteScriptWithResultAsync("get_user_name();");
string user_name = JSON.Parse(result_user_name.ResultAsJson).Value;//处理json串
var result_user_info = await webView.CoreWebView2.ExecuteScriptWithResultAsync("get_user_info();");
var json = JSON.Parse(result_user_info.ResultAsJson);//通过json["user_name"].Value 获取值 

C#发送数据,html接收

C#发送:

webView.CoreWebView2.PostWebMessageAsJson(reply);
webView.CoreWebView2.PostWebMessageAsString(dialog.Input.Text);

html接收数据:

window.chrome.webview.addEventListener('message', arg => {if ("WindowBounds" in arg.data) {document.getElementById("window-bounds").value = arg.data.WindowBounds;}if ("SetColor" in arg.data) {document.getElementById("colorable").style.color = arg.data.SetColor;}
});  

html发送数据,C#接收

html发送:

window.chrome.webview.postMessage("GetWindowBounds");

C#接收:

wvMain.WebMessageReceived += wvMain_WebMessageReceived;

C#增加和删除js脚本

Enter the JavaScript code to run as the initialization script that runs before any script in the HTML document.

在任何js脚本之前运行

string scriptId = await webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(dialog.Input.Text);
webView.CoreWebView2.RemoveScriptToExecuteOnDocumentCreated(scriptId);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/46389.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

AbpVnext系列三 添加种子项目

一、src下面增加DbMigrations类库,注意是要.Net Framework 类型的类库,不能是.Net Standard 的。 二、添加类库后为项目添加如上三个项目 appsetting.json 配置信息{"ConnectionStrings": {"AidenAdmin": "Server=127.0.0.1;port=3306;Database=…

6. 在WEB中应用MyBatis(使用MVC架构模式)

学习目标:掌握mybatis在web应用中怎么用 mybatis三大对象的作用域和生命周期 ThreadLocal原理及使用 巩固MVC架构模式 为学习MyBatis的接口代理机制做准备实现功能:银行账户转账 使用技术:HTML + Servlet + Mybatis1. 需求描述 ​​ 2. 数据库表的设计和准备数据 创建数据库…

数字园区规划

数字园区规划 | 数字经济产业园规划、数字孪生产业园区规划设计 2024-03-10 19:00书生产业规划内容导读: 【一】数字产业园区发展环境 【二】数字产业园区市场现状 【三】数字产业园区建设需求 【四】数字园区建设赋能手段 【五】数字园区规划建设建议当下,数字经济已上升为我…

Fortran哈希函数库的使用

哈希表hash table,类似于python中的字典,可以实现基于字符串的索引。即根据输入的数据(整数,浮点数,字符串等),对应到唯一的数据。这个特性对于气象编程中的根据站点信息检索数据十分有用。由于Fortran标准库中没有功能的实现,需要自己编写函数。github已经有大神编写好…

OpenCL体系结构分析

OpenCL体系结构分析 OpenCL是一个开放的行业标准,用于对组织到单个平台中的CPU、GPU和其他离散计算设备的异构集合进行编程。它不仅仅是一种语言。OpenCL是一个用于并行编程的框架,包括一种语言、API、库和一个支持软件开发的运行时系统。例如,使用OpenCL,程序员可以编写在…

Ax86uPro路由器多平台直播录制

开源项目:https://github.com/hr3lxphr6j/bililive-go 下载程序传到路由器【建议挂载移动硬盘】:路由器安装Entware环境登录到命令行执行: opkg update --no-check-certificat opkg install ffmpeg --no-check-certificat 到bililive-go程序目录执行: ./bililive-linux-arm…

mui里点击input框是为什么会返回顶部

原文 https://blog.csdn.net/weixin_44070058/article/details/123093978 删除 mui.min.js 里的这行代码 d.contains(c)&&(d.remove(c),setTimeout(function(){window.scrollTo(b.body.scrollLeft,b.body.scrollTop)},20))关联项目FreeSql QQ群:4336577BA & Blazo…

如何在Linux安装Python+JDK+Mysql+Tomcat+Django以及简单的跑一个java web项目和一个简单的Django项目

Linux 搭建Java web平台 一,Linux安装JDK ①下载安装包 解压 [root@wwww ~]# tar -zxvf jdk-linux-x64.tar.gz②移动到usr/local/java目录下③安装完成配置环境变量 vi /etc/profile 最后如下两行即可JAVA_HOME=/usr/local/java/jdk1.8 # 这是你放的jdk安装路径CLASSPATH=$JA…