C# 利用XejeN框架源码,编写一个在 Winform 界面上的语法高亮的编辑器,使用 Monaco 编辑器

news2025/1/21 12:14:39

析锦基于Monaco技术实现的Winform语法高亮编辑器

winform中,我们有时需要高亮显示基于某种语言的语法编辑器。

目前比较强大且UI现代化的,无疑是宇宙最强IDE的兄弟:VS Code。

类似 VS Code 的体验,可以考虑使用 Monaco Editor(VS Code 使用的编辑器)。虽然它主要用于 Web,但你可以在 WPF 或者 Winform 中嵌入一个浏览器控件(如 WebView2)并加载 Monaco Editor。

当然,适用于Winform的这种语法高亮的编辑器,除了Monaco外,还有AvalonEdit、ScintillaNET等,都可以用于复杂需求的高亮显示。



今天,我们只讲 Monaco 如何引入到 Winform 中。

本文是基于 XejeN 的 C/S 框架编写的,若您想了解 XejeN 的 C/S 框架,可以阅读此文章:
https://blog.csdn.net/mazhiyuan1981/article/details/138852326

若您想直接下载XejeN的 C/S 框架,可以访问:https://gitee.com/mazhiyuan1981/xejen-open.git

好的,下面我们开始介绍如何将 Monaco 编辑器引入到 Winform 中。


一、新建一个 Winform 项目

二、创建一个 Winform 窗体

窗体留出一个Panel控件,用于承载 Monaco 编辑器

三、安装必要的 Winform 浏览网页的 WebView2 控件

四、创建一个承载编辑器的网页界面

此为重点,这个html页面,将会显示和编辑数据内容,并能获取编辑器内容。

主要是通过setEditorContent和getEditorContent这两个方法完成的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Monaco Editor</title>
    <link rel="stylesheet" data-name="vs/editor/editor.main" href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.31.1/min/vs/editor/editor.main.css">
    <style>
        html, body, #container {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
            overflow: hidden;
        }

        #container {
            display: flex;
        }
    </style>
</head>
<body>
    <div id="container"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.31.1/min/vs/loader.js"></script>
    <script>
        require.config({ paths: { 'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.31.1/min/vs' } });
        window.MonacoEnvironment = { getWorkerUrl: function (workerId, label) { return `data:text/javascript;base64,${btoa("self.MonacoEnvironment = { baseUrl: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.31.1/min/' }; importScripts('https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.31.1/min/vs/base/worker/workerMain.js');")}` } };

        require(['vs/editor/editor.main'], function () {
            window.editor = monaco.editor.create(document.getElementById('container'), {
                value: "",
                language: 'plaintext',
                automaticLayout: true  // This line ensures the editor adjusts to its container's size
            });

            window.addEventListener('resize', () => {
                window.editor.layout();  // Adjust editor layout on window resize
            });

            window.chrome.webview.postMessage('initialized');
        });

        window.setEditorContent = function (content, language) {
            window.editor.setValue(content);
            monaco.editor.setModelLanguage(window.editor.getModel(), language);
        };

        window.getEditorContent = function () {
            return window.editor.getValue();
        };
    </script>
</body>
</html>

五、在 Winform 窗体界面中,加载编辑器并执行

        private void LoadEditorAsync()
        {
            if (string.IsNullOrEmpty(Data)) return;

            string content;
            string language;

            if (Data.IsJson())
            {
                content = Data.FormatJson();
                language = "json";
            }
            else if (Data.IsXml())
            {
                content = Data.FormatXml();
                language = "xml";
            }
            else
            {
                content = Data;
                language = "plaintext";
            }

            string htmlPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "monaco-editor.html");

            DataTextBox.CoreWebView2InitializationCompleted += (sender, args) =>
            {
                if (!args.IsSuccess)
                {
                    MessageBox.Show("WebView2 initialization failed.");
                    return;
                }

                DataTextBox.CoreWebView2.WebMessageReceived += (sender2, args2) =>
                {
                    if (args2.TryGetWebMessageAsString() == "initialized")
                    {
                        DataTextBox.CoreWebView2.ExecuteScriptAsync($"setEditorContent({JsonConvert.SerializeObject(content)}, '{_language ?? language}');");
                        SaveButton.Enabled = true;
                    }
                };

                DataTextBox.CoreWebView2.NavigateToString(File.ReadAllText(htmlPath));
            };

            DataTextBox.Source = new Uri(htmlPath);
        }

六、获取编辑器修改后的内容
 

        /// <summary>
        /// 获取文本数据内容
        /// </summary>
        /// <returns></returns>
        public async Task<string> GetDataAsync()
        {
            return JsonConvert.DeserializeObject(await DataTextBox.CoreWebView2.ExecuteScriptAsync("getEditorContent();")).ToString();
        }

使用GetDataAsync方法,去调用html页面的js方法getEditorContent,便可以取到编辑器的内容

七、将monaco-editor.html设置为:如果较新则复制


 

完整源码位置在:

完整Demo演示位置在:

源码位置:https://gitee.com/mazhiyuan1981/xejen-open.git

祝您用餐愉快。

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

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

相关文章

每日一题——冒泡排序

C语言——冒泡排序 冒泡排序练习 前言&#xff1a;CSDN的小伙伴们&#xff0c;大家好&#xff01;今天我来给大家分享一种解题思想——冒泡排序。 冒泡排序 冒泡法的核心思想&#xff1a;两两相邻的元素进行比较 2.冒泡排序的算法描述如下。 (1)比较相邻的元素。如果第一 个比…

ARCGIS 如何对河流等线条图形进行Smooth处理——具有多个断点高阶版

1.线转点折点&#xff08;注意&#xff01;很重要&#xff0c;不是线转点&#xff09; 2.点转线步骤 ## 3 线的融合 2.1 新建Filed 》短精度类型》利用选择工具的 线文件。全选同一条河流点&#xff0c;进入Tabel的选择界面。给同一条河赋值同一个值。 大功告成&#xff01;…

JS安全应用

JS应用 常见分析调试&#xff1a; -代码全局搜索 案例 登录框&#xff0c;可以看到发送用户名密码被JS加密 搜索Username&#xff0c;找到加密地方 logindata.UserName encodeURI(encrypt.encrypt(numMobile));logindata.Mobile encodeURI(encrypt.encrypt(numMobile));…

Jmeter如何进行分布式测试

使用Jmeter进行性能测试时&#xff0c;有些同学问我如果并发数比较大(比如最近项目需要支持1000并发)&#xff0c;单台电脑的配置(CPU和内存)可能无法支持&#xff0c;怎么办就需要使用分布式压测 1.分布式原理&#xff1a; 1、Jmeter分布式测试时&#xff0c;选择其中一台作…

视频融合共享平台LntonCVS视频监控管理平台技术方案详细介绍

LntonCVS国标视频综合管理平台是一款以视频为核心的智慧物联应用平台。它基于分布式、负载均衡等流媒体技术进行开发&#xff0c;提供广泛兼容、安全可靠、开放共享的视频综合服务。该平台具备多种功能&#xff0c;包括视频直播、录像、回放、检索、云存储、告警上报、语音对讲…

jpa下hibernate的ddl-auto的各种属性

在jpa中ddl-auto一共有四种&#xff0c;分别为&#xff1a; ddl-auto&#xff1a;create ----每次运行该程序&#xff0c;没有表格会新建表格&#xff0c;表内有数据会清空&#xff1b; ddl-auto&#xff1a;create-drop ----每次程序结束的时候会清空表 ddl-auto&#xff1a;…

2024最新IDEA插件开发+发布全流程 SelectCamelWords[选中驼峰单词](idea源代码)

2024最新IDEA插件开发&#xff08;发布&#xff09;-SelectCamelWords[选中驼峰单词]&#xff08;idea源代码&#xff09; 参考文档 Jetbrains Idea插件开发文档: https://plugins.jetbrains.com/docs/intellij/welcome.html代码地址&#xff1a;https://github.com/yangfeng…

如何覆盖!important修饰的属性

最简单的方法 如果这个!important修饰的属性 是自己的写的&#xff0c;去掉这种写法&#xff0c;使用优先级的方式来写这个属性&#xff08;.outter .inner 的优先级就会比 。outter的优先级高&#xff09; 复杂的方法&#xff1a;用魔法打败魔法 但是这个样式来自于全局css&am…

代码随想录——子集Ⅱ(Leecode 90)

题目链接 回溯 class Solution {List<List<Integer>> res new ArrayList<List<Integer>>();List<Integer> list new ArrayList<Integer>();boolean[] used; public List<List<Integer>> subsetsWithDup(int[] nums) {use…

Maven 插件列表详解

Maven 是一个强大的项目管理和构建工具&#xff0c;广泛应用于 Java 项目中。作为一款优秀的构建管理工具&#xff0c;Maven 不仅提供了标准化的项目结构和依赖管理&#xff0c;还通过其丰富的插件系统&#xff0c;极大地扩展了其功能和灵活性。无论是代码编译、测试、打包&…

第55期|GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以找…

怎样搭建serveru ftp个人服务器

首先说说什么是ftp&#xff1f; FTP协议是专门针对在两个系统之间传输大的文件这种应用开发出来的&#xff0c;它是TCP/IP协议的一部分。FTP的意思就是文件传输协议&#xff0c;用来管理TCP/IP网络上大型文件的快速传输。FTP早也是在Unix上开发出来的&#xff0c;并且很长一段…

【linux】内核从tcp层调用IP层摸索中

合入代码&#xff1a; 登录 - Gitee.com 这是运行日志&#xff1a; https://gitee.com/r77683962/linux-6.9.0/raw/master/test_log/kern_tcp_ip.log 日志截取部分&#xff08;也不知道对不对&#xff0c;凭感觉走。。。。&#xff09;

「51媒体」电视台媒体邀约采访报道怎么做?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 电视台作为地方主流媒体&#xff0c;对于新闻报道有着严格的选题标准和报道流程。如果您希望电视台对某个会议或活动进行报道&#xff0c;可以按这样的方法来做&#xff1a; 1.明确活动信…

BizDevOps全局建设思路:横向串联,纵向深化

本文来自腾讯蓝鲸智云社区用户&#xff1a;CanWay BizDevOps概述 IT技术交付实践方法在不断迭代中持续优化。在工业化时代&#xff0c;Biz&#xff08;业务&#xff09;、Dev&#xff08;开发&#xff09;、Ops&#xff08;运维&#xff09;三者往往相对分离&#xff0c;甚至有…

Python3 Matplotlib展示数据

matplotlib 是一个 Python 库&#xff0c;用于创建各种类型的图表和可视化。它提供了一个类似于 MATLAB 的绘图界面&#xff0c;使用户能够轻松地绘制线图、散点图、直方图、饼图等各种图表类型。matplotlib 可以在 Python 脚本、IPython shell、Jupyter Notebook 等环境中使用…

《梦醒蝶飞:释放Excel函数与公式的力量》3.3常用数学函数:AVERAGE

3.3常用数学函数&#xff1a;AVERAGE 在Excel中&#xff0c;AVERAGE 函数用于计算一系列数值的平均值。这个函数在数据分析中非常有用&#xff0c;因为它可以快速提供数值集的中心趋势。 1)基本语法&#xff1a; AVERAGE(range) 或者 AVERAGE(number1,[number2,...]) ran…

Jetpack Compose_Alignment对其+Arrangement排列

文章目录 1.Alignment 对齐1.1Alignment 对齐方式1.2AbsoluteAlignment 绝对对齐1.3BiasAlignment 偏差对齐1.4BiasAbsoluteAlignment偏差绝对对齐 2.Arrangement 排列2.1Arrangement 排列方式2.2Arrangement.Horizontal2.3Arrangement.Vertical 1.Alignment 对齐 1.1Alignmen…

Linux之旅: 基础知识点的终极指南

文章目录 1、Linux的目录结构2、ls命令3、管理文件和目录4、linux命令使用细节和技巧5、权限管理基本命令6、搜索命令7、管道符与重定向8、压缩和解压命令9、用户及vim编辑器10、用户和用户组管理一、Linux系统用户账号的基本管理二、Linux系统用户组的管理 1、Linux的目录结构…

大数据集群离线解析经纬度逆编码地址

背景 最近有个需要需求把经纬度解析为地址&#xff0c;那么通常解析地址市面上流行的方案就是调取百度、高德地图的接口进行解析。 难点 但是在用这个方案遇到一个问题就是企业认证的百度地图每天的逆编码解析为300w次&#xff0c;qps为100次/秒&#xff0c;对于日增上千万的…