在WinForm中使用Html—— NanUI 1.0 踩坑小结

前情提要

最近在做一个中间件,用于PC蓝牙连接->转发数据给Unity做的VR客户端
之前是直接用.Net控制台写的,但是考虑到没有图形界面,对于非开发者来说不太好用,遂想着做个带界面的版本。
WinForm不太会用,加上也丑,就找找看有没有View这一层的新东西,真让我找到了
https://gitee.com/dotnetchina/NanUI
作者是这样介绍的
WinFormium 是 .NET 平台上的一个开源框架(曾用名:NanUI),用于使用 HTML5、CSS3 和 JavaScript 创建 WinForm 应用程序的用户界面。 它基于 Xilium.CefGlue 项目,该项目是 Chromium Embedded Framework (CEF) 的 .NET 实现。
如果您正在寻找一个用于创建具有现代用户界面的 WinForm 应用程序的框架,WinFormium 是一个不错的选择。 您可以使用 HTML、CSS 和 JavaScript 创建用户界面,并使用 C# 编写应用程序的业务逻辑。

安装好,解决好一系列问题,进入编写阶段。文档稍微有点晦涩(可能因为我是Unity开发)踩了一堆坑之后算是实现了我最需要的两个功能

1.点击前端按钮,带参调用C#方法

C#端

class MyWindow : Formium
{
    public MyWindow()
    {
        Url = "D:\\NetProject\\test\\test\\wwwroot\\Test.Html";
        MapClrObjectToJavaScript();
    }

    protected override FormStyle ConfigureWindowStyle(WindowStyleBuilder builder)
    {
        // 此处配置窗口的样式和属性,或留空以使用默认样式

        var style = builder.UseSystemForm();

        style.TitleBar = true;

        style.DefaultAppTitle = "My first WinFomrim app";

        return style;
    }
    private void MapClrObjectToJavaScript()
    {
        RegisterJavaScriptMessagHandler("MessagHandler", args =>
        {
            OnlyUseVoid(args);
        });

    }
    void OnlyUseVoid(string args)
    {
        Debug.WriteLine(args);
    }
}

Html代码

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>NanUI测试</title>
<script>
    function MessagHandler() {
        formium.postMessage("MessagHandler", "向消息通知器传参");
    }
</script>
</head>
<body>
    <button name="test1" onClick="MessagHandler()">向注册的方法传参</button>
</body>
</html>

输出结果
在这里插入图片描述
在这里插入图片描述

2. 前端实时获取C#端计算好的数据

C#端

using System.Reflection;
using System.Threading.Tasks;
using System;
using WinFormium;
using WinFormium.Forms;
using WinFormium.JavaScript;
using System.Windows.Forms;
using System.Diagnostics;
using System.Linq;

class MyWindow : Formium
{
    public MyWindow()
    {
        Url = "D:\\NetProject\\test\\test\\wwwroot\\Test.Html";
        Loaded += UpDateData;
    }

    protected override FormStyle ConfigureWindowStyle(WindowStyleBuilder builder)
    {
        // 此处配置窗口的样式和属性,或留空以使用默认样式

        var style = builder.UseSystemForm();

        style.TitleBar = true;

        style.DefaultAppTitle = "My first WinFomrim app";

        return style;
    }
    void UpDateData(object sender, BrowserEventArgs e)
    {
        var frame = e.Browser.GetMainFrame();
        var hbrjso = BeginRegisterJavaScriptObject(frame);
        var obj = new JavaScriptObject();
        obj.Add("async", async (args, promise) =>
        {
            string Hex = GenerateRandomHex();

            await Task.Delay(100);

            if (Hex != null)
            {
                promise.Resolve(new string(Hex.ToArray()));               
            }
            else
            {
                promise.Reject("Rejected by random.");
            }
        });
        RegisterJavaScriptObject(hbrjso, "UpDateData", obj);//注册这个异步方法
        EndRegisterJavaScriptObject(hbrjso);
    }
    private static Random random = new Random();
    public static string GenerateRandomHex()//随机输出一个像Hex的数据
    {
        const string hexChars = "0123456789ABCDEF";
        char[] buffer = new char[16]; // 16 characters for 16 bytes

        for (int i = 0; i < buffer.Length; i++)
        {
            buffer[i] =  hexChars[random.Next(hexChars.Length)];
        }

        return DateTime.Now.ToString() + new string(buffer);
    }
}

HTML

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>NanUI测试</title>
<style>
    #dataContainer {
        height: 300px; /* 设置一个固定的高度 */
        overflow-y: auto; /* 当内容超出高度时,显示滚动条 */
        border: 1px solid #ccc; /* 可选,为容器添加边框 */
        padding: 10px; /* 可选,为容器添加内边距 */
    }
</style>
<script>
    function SyncUpDateData() {
        var promise = window.external.UpDateData.async(1);
        promise.then(
            res => {
                // 创建一个新的 div 元素来显示数据
                var newDiv = document.createElement('div');
                newDiv.innerText = res;

                // 将新的 div 元素添加到滚动容器中
                var container = document.getElementById('dataContainer');
                container.appendChild(newDiv);

                // 如果需要,可以在这里实现自动滚动到最新的数据
                container.scrollTop = container.scrollHeight;
            })
            .catch(
                err => {
                    console.error(err);
                });
    }
    setInterval(SyncUpDateData, 100);
</script>
</head>
<body>
    <div id="dataElement">异步更新数据测试</div>
    <div id="dataContainer"></div>
</body>
</html>

运行结果
在这里插入图片描述
好了 总结完毕 用的不一定对 不知道这么玩会不会有什么性能问题 下面进入正式开发如果还有坑再更新吧
源码自取 懒得弄Git了 直接百度云吧~ 跑不起来不要问我 去问作者 这个库的Gitee主页也有文档
通过网盘分享的文件:test.zip
链接: https://pan.baidu.com/s/1fDGOordmwjhEw-aM6wJ69Q?pwd=s46e 提取码: s46e
–来自百度网盘超级会员v7的分享

思考

  1. 看似解决了图形界面的问题,其实调用起来还是挺麻烦的(* _ *)
  2. 包体好大,毕竟里面封装了个浏览器(* _ *)
  3. 图形界面可以直接交给前端写了(这不就是前后端分离?)(^ _ ^)
  4. 不用学WinFrom图形界面相关的知识了(^ _ ^)
  5. 做出来的界面好看(^ _ ^)
  6. 我做上位机/中间件要那么好看干嘛(* _ *)
  7. 折腾一圈,纯给自己找乐子了…
  8. 感谢@chunweiruan老哥,顺着老哥的踩坑记录走下来点播了我很多地方
    老哥的踩坑记录,点进主页一共七篇
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值