WinForm(十三)WebView2

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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.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;
            
        
    

运行结果:

以上是关于WinForm(十三)WebView2的主要内容,如果未能解决你的问题,请参考以下文章

WebView2如何加载本地文件?

番号怎么用 番号使用方法

隐藏磁力链接怎么搜

C#开发BIMFACE系列53 WinForm程序中使用CefSharp加载模型图纸1 简单应用

text 邮便番号自动入力

javascript 电话番号コンポーネント