WinForm(十三)WebView2

WebView是WinForm框架中一个控件,用来对网页信息交互,有时Web自己开发的,有时Web是三方的。

下面通过一个例子来看看WebView2的使用。

首先看Web的逻辑,是一个商品添加页面,用AlpineJS和BootStrap来开发的,业务上点击添加按钮,弹出modal框窗,然后保存结果,完成添加,代码如下:

View

@{ViewData["Title"] = "商品管理";
}
@section Css{<style>.form-switch {display: flex !important;flex-direction: row-reverse !important;justify-content: space-between !important;}
</style>
}
<div x-data="querydata()" id="ttt"><div class="row" style="margin:4px"><div class="col-sm-4"></div><div class="col-sm-4"></div><div class="col-sm-4" style="text-align:right" style="margin:4px 0px"><button type="button" class="btn btn-info" data-bs-toggle="modal" data-bs-target="#addgoods">追加</button></div></div><hr /><div class="mb-3 row"><table class="table table-striped"><thead><tr><th>ID</th><th>名前</th><th>価格</th><th>説明</th><th>有効</th><th>シリアル番号</th><th>製品タイプ</th><th>操作</th></tr></thead><tbody><template x-for="goods in Goodses"><tr><td x-text="goods.ID"></td><td x-text="goods.Name"></td><td x-text="goods.Price"></td><td x-text="goods.Describe"></td><td x-text="goods.Validate"></td><td x-text="goods.SerialNumber"> </td><td x-text="goods.GoodsType"></td><td><button type="button" class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#modifygoods" x-on:click="modify(goods)">改訂</button><button type="button" class="btn btn-danger btn-sm" x-on:click="remove(goods.ID)">消去</button></td></tr></template></tbody></table></div><div class="modal fade" id="addgoods" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true"><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><h5 class="modal-title" id="staticBackdropLabel"> 追加Goods</h5><button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button></div><div class="modal-body"><div class="container-fluid"><div class="mb-3 row"><label for="GoodsTypeID" class="col-sm-4 col-form-label">Goodsタイプ</label><div class="col-sm-8"><select class="form-select" x-model="Goods.GoodsTypeID" id="GoodsTypeID" aria-label="Default select example"><option selected>製品タイプ</option><template x-for="(item,index) in GoodsTypes" :key="index"><option x-text="item.Name" :value="item.ID"></option></template></select></div></div><div class="mb-3 row"><label for="name" class="col-sm-4 col-form-label">お名前</label><div class="col-sm-8"><input type="text" class="form-control" x-model="Goods.Name" placeholder="" id="Name"></div></div><div class="mb-3 row"><label for="Price" class="col-sm-4 col-form-label">価格</label><div class="col-sm-8"><input type="number" class="form-control" x-model="Goods.Price" placeholder="" min="1" id="Price"></div></div><div class="mb-3 row"><label for="Describe" class="col-sm-4 col-form-label">説明</label><div class="col-sm-8"><input type="text" class="form-control" x-model="Goods.Describe" placeholder="" min="1" id="Describe"></div></div><div class="mb-3 row"><label for="SerialNumber" class="col-sm-4 col-form-label">シリアル番号</label><div class="col-sm-8"><input type="number" class="form-control" x-model="Goods.SerialNumber" placeholder="" min="1" id="SerialNumber"></div></div><div class="form-check form-switch mb-3 row" style="margin-left:150px"><label class="form-check-label" for="IsCollapse">有効</label><input class="form-check-input" type="checkbox" role="switch" x-model="Goods.Validate" id="Validate" checked></div><div></div></div><div class="modal-footer"><button type="button" class="btn btn-secondary" data-bs-dismiss="modal">閉鎖</button><button type="button" class="btn btn-primary" data-bs-dismiss="modal" x-on:click="sava">保存</button></div></div></div></div></div>@section Scripts{<script src="~/js/Alpine.js" defer></script><script>function querydata() {return {GoodsTypes: [],Goodses: [],Goods: {Name: '',Price: 0,Describe: '',Validate: true,SerialNumber: 0,GoodsTypeID: 0,GoodsType: '',},init() {that = this$.get("/home/goodses", {}, function (data) {if (data != null) {that.GoodsTypes = data.Data.GoodsTypesthat.Goodses = data.Data.Goodses} else {console.log("/Home/Goodses is error")}});},sava() {$.ajax({type: "POST",url: "/home/goods",data: this.Goods,success: function (data) {if (data.Result) {alert("送信に成功!")that.init()that.Goods = {Name: '',Price: 0,Describe: '',Validate: true,SerialNumber: 0,GoodsTypeID: 0,GoodsType: '',}} else {alert("提出に失敗しました:" + data.Message)}}});}}}
</script>}
</div>

Controller

using Microsoft.AspNetCore.Mvc;
using System.Collections.Immutable;
using System.Diagnostics;
using WinFormDemo12WebHost.Models;namespace WinFormDemo12WebHost.Controllers
{public class HomeController : Controller{private readonly ILogger<HomeController> _logger;public HomeController(ILogger<HomeController> logger){_logger = logger;}public IActionResult Goods(){return View();}static List<GoodsType> _goodsTypes = new List<GoodsType> {new GoodsType {ID=1,Name="A类型" },new GoodsType {ID=2,Name="B类型" },};static List<Goods> _goodses = new List<Goods>{};[HttpGet("/home/goodses")]public async Task<JsonResult?> QueryGoodsesAsync(){try{_logger.LogInformation("BackQuery Goods List");var goodsTypes = _goodsTypes;var goodses = _goodses;return new JsonResult(new{Data = new{GoodsTypes = goodsTypes,Goodses = goodses}});}catch (Exception exc){_logger.LogCritical(exc, exc.Message);return new JsonResult(new{Result = false,Message = exc.Message});}}[HttpDelete("/home/goods")]public async Task<JsonResult?> DeleteGoodsAsync(int id){try{_logger.LogInformation("delete goods");var result = _goodses.Remove(_goodses.SingleOrDefault(s => s.ID == id));return new JsonResult(new{Result = result});}catch (Exception exc){_logger.LogCritical(exc, exc.Message);return new JsonResult(new { Result = false, Message = exc.Message });}}[HttpPut("/home/goods")]public async Task<JsonResult?> ModifyGoodsAsync(Goods goods){try{_logger.LogInformation("modify goods");_goodses.Remove(_goodses.SingleOrDefault(s => s.ID == goods.ID));goods.ID = _goodses.Max(s => s.ID) + 1;_goodses.Add(goods);return new JsonResult(new{Result = goods});}catch (Exception exc){_logger.LogCritical(exc, exc.Message);return new JsonResult(new { Result = false, Message = exc.Message });}}[HttpPost("/home/goods")]public async Task<JsonResult?> AddGoodstAsync(Goods goods){try{_logger.LogInformation("add goods");goods.ID = _goodses.Count > 0 ? _goodses.Max(s => s.ID) + 1 : 1;_goodses.Add(goods);return new JsonResult(new{Result = true,Data = goods});}catch (Exception exc){_logger.LogCritical(exc, exc.Message);return new JsonResult(new { Result = false, Message = exc.Message });}}   }public class GoodsType{public int ID { get; set; }public string? Name { get; set; }}public class Goods{public int ID { get; set; }public string? Name { get; set; }public decimal Price { get; set; }public string? Describe { get; set; }public bool Validate { get; set; }public int GoodsTypeID { get; set; }public int SerialNumber { get; set; }public string GoodsType { get; set; }public decimal MaxPrice{get{return Price >= 70000 ? Price + 3000 : (Price > 0 ? Price + 2000 : 0);}}public decimal MinPrice{get{return Price >= 70000 ? Price - 3000 : (Price > 2000 ? Price - 2000 : 0);}}}
}

WebView2与控件与Web的交互主要通过webView21.CoreWebView2.ExecuteScriptAsync方法完成,所以不同的Web内容,JS的写法不一样,当然这里的JS实现简单交互还行,更复杂的就有点吃力了,可以使用一些UI自动化工库来操作更快捷。在WinForm中使用WebView,更多的是用来展现数据,而不是互操作,所以下面只是一个简单交互例子而已。

下面是模拟三个动作:点击添加按钮,在商品添加页面中完成信息录入,然后点击保存按钮(即使保存成功或失败后的alter也能针对处理)。

using System.Collections.Generic;namespace WinFormsDemo13
{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){webView21.Source = new Uri(@"http://localhost:5026/home/goods");}private void button1_Click(object sender, EventArgs e){var js = """$(".btn-info").click()""";webView21.CoreWebView2.ExecuteScriptAsync(js);}int sn = 1;private void button2_Click(object sender, EventArgs e){int mark = DateTime.Now.Millisecond * 1000 + DateTime.Now.Microsecond;var js = $"""   var goods=document.querySelector('[x-data]')._x_dataStack[0].Goods;goods.GoodsTypeID={mark % 2 + 1};goods.Name="商品{mark}";goods.Price={100 * new Random().Next(1, 20)};goods.Describe="商品{mark}说明";goods.SerialNumber={sn};goods.Validate={(mark % 2 == 0).ToString().ToLower()};goods.GoodsType="{(mark % 2 == 0 ? "A类型" : "B类型")}";""";webView21.CoreWebView2.ExecuteScriptAsync(js);sn++;}private void button3_Click(object sender, EventArgs e){var js = """$("#addgoods .btn-primary").click()""";webView21.CoreWebView2.ExecuteScriptAsync(js);}     private void CoreWebView2_ScriptDialogOpening(object? sender, Microsoft.Web.WebView2.Core.CoreWebView2ScriptDialogOpeningEventArgs e){e.Accept();}private void webView21_CoreWebView2InitializationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e){if (e.IsSuccess){webView21.CoreWebView2.Settings.AreDefaultScriptDialogsEnabled = false;webView21.CoreWebView2.ScriptDialogOpening += CoreWebView2_ScriptDialogOpening;}}}
}

运行结果:

5a009b34d682593c5f81f2128e2c4419.png

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Fluent UDF【4】:C语言

Fluent UDF利用的是C语言&#xff0c;本文简单介绍在UDF中经常会用到的C语言常识。 本文部分内容来自UDF手册。 1 C语言中的注释 C语言中的注释利用/*及*/来实现。例如: /*这是一个注释*/ 注释也可以跨行实现&#xff0c;如: /*这是一个 跨行注释*/ 注意:在编写UDF的过程中&…

java 画砖块,钢笔画入门:教你画砖块

说到砖块很多朋友会想到搬砖&#xff0c;绘画吧今天要教大家用钢笔画一块砖&#xff0c;因为画建筑的时候经常要画砖墙&#xff0c;我们先从简单的砖块学起&#xff0c;之后绘画吧会给大家分享画一面砖墙的哦。绘制要点&#xff1a;本教程的主体物选择了一块有小残缺面的砖头。…

[转] Node.js的线程和进程

[From] http://www.admin10000.com/document/4196.html 前言 很多Node.js初学者都会有这样的疑惑&#xff0c;Node.js到底是单线程的还是多线程的&#xff1f;通过本章的学习&#xff0c;能够让读者较为清晰的理解Node.js对于单/多线程的关系和支持情况。同时本章还将列举一些让…

第三方支付异步通知的陷阱

版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 https://blog.csdn.net/j16421881/article/details/78703792 用户下单后调用第三方支付付款&#xff0c;然后接收第三方支付的异步通知&#xff0c;以便确认支付是否成功。 如下图 但异步通知可能…

2.3 万 Star,Nginx 可视化配置工具

你好&#xff0c;这里是 Dotnet 工具箱&#xff0c;定期分享 Dotnet 有趣&#xff0c;实用的工具或组件&#xff0c;希望对您有用&#xff01;对于前后端开发工程师来说&#xff0c; Nginx 是必须掌握的工具&#xff0c;因为它不仅仅是一个 Web Server&#xff0c;还包含了其他…

城市智慧停车系统方案的产品设计体系介绍

最近几年随着大数据技术快速发展与应用&#xff0c;智慧城市随即被正式提出。而且&#xff0c;我们也可以深刻感受到“智慧”正在慢慢改变我们的生活方式和城市。要让城市变智慧的地方太多太多&#xff0c;当前我们接触做多的可能就是外出停车&#xff0c;比如很多商场的停车系…

vue.js:利用vue.js做一个抽奖小游戏

MVVM模式是什么&#xff1a;MModel(模型)&#xff0c;VView&#xff08;视图&#xff09;,VM ViewModel(简写成MVVM) . 代码如下&#xff1a; 运行代码结果&#xff1a; 1.你没有中奖&#xff1a; 2.恭喜你&#xff0c;你中奖了&#xff1a; 转载于:https://www.cnblogs.com/ya…

滚动加载数据 php,无刷新动态加载数据 滚动条加载适合评论等页面

滚屏加载更多数据,适合评论等页面本例的数据库很简单&#xff0c;一看就明了复制代码 代码如下:$querymysql_query("select * from content order by id desc limit 0,10");while ($rowmysql_fetch_array($query)) {?>js文件复制代码 代码如下:$(function(){var …

国际主流固件接口组织UEFI全面支持LoongArch,龙架构已完成上游TianoCore EDK2代码合并...

2022年9月初&#xff0c;UEFI官方组织在发布的UEFI specification V2.10规范中全面支持了LoongArch64架构以及部分LoongArch32架构。近期&#xff0c;龙芯团队又完成了LoongArch基础代码与UEFI上游TianoCore EDK2的合并&#xff0c;LoongArch进入TianoCore EDK2主分支&#xff…

Invalidate和postInvalidate

为什么80%的码农都做不了架构师&#xff1f;>>> Android提供了Invalidate方法实现界面刷新&#xff0c;但是Invalidate不能直接在线程中调用&#xff0c;因为他是违背了单线程模型&#xff1a;android UI操作并不是线程安全的&#xff0c;并且这些操作必须在UI线程…

.Net轻松处理亿级数据--clickhouse及可视化界面安装介绍

前言我是在17年就听说过Clickhouse,那时还未接触过亿数据的运算&#xff0c;那时我在的小公司对于千万数据的解决方案还停留在分库分表&#xff0c;最好的也是使用mycat做的集群。这些解决方案都比较复杂&#xff0c;毕竟通常来说那些需要大量存储的数据基本都是像日志&#xf…

NET CORE读取Excel.xlsx单元格内的图片,并关联当前业务ID推送图片到指定服务器...

NET CORE读取Excel.xlsx单元格图片的场景&#xff0c;一般是批量导入业务数据&#xff0c;例如&#xff1a;药品的图片&#xff0c;医师资格证&#xff0c;商品上架、商家营业资质、水果信息、用户头像等等这里我截个图&#xff0c;图文并茂更好理解特别声明&#xff1a;粘贴图…

RocketMQ 5.0 大手笔,拥抱云原生,支持流处理,高可用架构升级!

大家好&#xff0c;我是君哥。RocketMQ 5.0 已经发布一段时间了&#xff0c;今天来分享一下 RocketMQ 5.0 有哪些新特性。1 架构变化RocketMQ 5.0 架构上的变化主要是为了更好的走向云原生。RocketMQ 4.x 架构如下&#xff1a;Broker 向 Name Server 注册 Topic 路由信息&#…

php验证码显示乱码,如何解决php验证码乱码问题

php验证码乱码的解决办法&#xff1a;1、修改访问验证码生成方法函数的路径&#xff1b;2、修改文件编码&#xff0c;并去掉BOM头&#xff1b;3、检查验证码生成方法&#xff1b;4、修改服务环境。具体问题&#xff1a;php验证码输出全是乱码...<?php session_start();head…

中国HBase技术社区第五届MeetUp ——HBase技术解析及应用实践(深圳站)

HBase—Hadoop Database是一个分布式的、面向列的开源数据库&#xff0c;该技术来源于 Fay Chang 所撰写的Google论文“Bigtable&#xff1a;一个结构化数据的分布式存储系统”。HBase的特点是高可靠性、高性能、面向列、可伸缩的分布式存储系统&#xff0c;如今HBase已经广泛应…

如何查找Power BI本地报表服务器产品密钥

Power BI 报表服务器产品密钥&#xff0c;以便在生产环境中安装服务器。 已下载 Power BI 报表服务器&#xff0c;并已购买 SQL Server Enterprise 软件保障协议。 或者&#xff0c;已购买 Power BI Premium。 希望在生产环境中安装服务器&#xff0c;但需要产品密钥才能进行安…

【.NET番外篇】Rust环境搭建+基础开发入门+Rust与.NET6、C++的基础运算性能比较

前言&#xff1a;突然想打算把Rust作为将来自己主要的副编程语言。当然&#xff0c;主语言还是C#&#xff0c;毕竟.NET平台这么强大&#xff0c;写起来就是爽。缘起&#xff1a;之前打算一些新的产品或者新的要开发的东西&#xff0c;由于没有历史包袱&#xff0c;就想重新选型…

团队-中国象棋-最终程序

托管平台地址:https://gitee.com/zhanghongjian666/ZhongGuoXiangQi 小组名称:exciting 小组成员合照: 程序运行方法:html 程序运行示例及运行结果:转载于:https://www.cnblogs.com/qwsa/p/7944093.html

java原子类场景,CAS你知道吗?原子类AtomicInteger的ABA问题谈谈?,原子共面问题...

CAS你知道吗&#xff1f;原子类AtomicInteger的ABA问题谈谈&#xff1f;&#xff0c;原子共面问题(1)CAS是什么&#xff1f;比较并交换举例1, CAS产生场景代码&#xff1f;importjava.util.concurrent.atomic.AtomicInteger;public classCASDemo {public static voidmain(Stri…

深入分析JavaWeb Item7 -- HttpServletResponse详解

Web服务器收到客户端的http请求&#xff0c;会针对每一次请求&#xff0c;分别创建一个用于代表请求的request对象、和代表响应的response对象。request和response对象即然代表请求和响应&#xff0c;那我们要获取客户机提交过来的数据&#xff0c;只需要找request对象就行了。…