赞
踩
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.GoodsTypes
- that.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;
- }
- }
- }
- }

运行结果:
技术群:添加小编微信并备注进群
小编微信:mm1552923
公众号:dotNet编程大全
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。