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

析锦基于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这两个方法完成的

html 复制代码
<!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 窗体界面中,加载编辑器并执行

cs 复制代码
        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);
        }

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

cs 复制代码
        /// <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

祝您用餐愉快。

相关推荐
a***560628 分钟前
Windows上安装Go并配置环境变量(图文步骤)
开发语言·windows·golang
San30.34 分钟前
ES6+ 新特性解析:让 JavaScript 开发更优雅高效
开发语言·javascript·es6
烤麻辣烫1 小时前
黑马程序员苍穹外卖(新手)DAY6
java·开发语言·学习·spring·intellij-idea
友友马1 小时前
『QT』窗口 (一)
开发语言·数据库·qt
APIshop1 小时前
Python 零基础写爬虫:一步步抓取商品详情(超细详解)
开发语言·爬虫·python
AI科技星2 小时前
为什么宇宙无限大?
开发语言·数据结构·经验分享·线性代数·算法
Appreciate(欣赏)2 小时前
JAVA使用poi类读取xlxs文件内容拼接成添加数据SQL
java·开发语言·sql
oioihoii3 小时前
性能提升11.4%!C++ Vector的reserve()方法让我大吃一惊
开发语言·c++
毕设源码-朱学姐3 小时前
【开题答辩全过程】以 基于JAVA的恒星酒店客房管理系统为例,包含答辩的问题和答案
java·开发语言
思密吗喽3 小时前
景区行李寄存管理系统
java·开发语言·spring boot·毕业设计·课程设计