【请注意:此文已过期,0.6版NanUI实现方式不同!!!】

经过了这一个多星期的调整与修复,NanUI for .NET Winform的稳定版已经发布。应广大群友的要求,现已将NanUI的全部代码开源。

GitHub: https://github.com/NetDimension/NanUI

Release: https://github.com/NetDimension/NanUI/releases

这次发布的是一个相对稳定的版本,解决和改善了如下问题:

  • 页面随机白屏问题(主要原因是GC自动回收后,造成内存地址不可读)
  • NanUI编译版本改为.NET 4.0 Client Profile
  • 托上面那条改进的福,NanUI现在支持Windows XP了
  • 不再支持本地CEF运行支持文件,现在支持文件都需要在线下载安装,当然也可以手动下载离线包安装,但是不论那种方式,CEF都安装到一个共享的位置。CEF运行库只需下载安装一次,不会多次下载。

欢迎下载把玩,也欢迎进群讨论,群号241088256。

下面,进入我们的正题,使用NanUI以及手边的各种开源库制作一个所见即所得的Markdown编辑器。

NanUI系列目录

NanUI for Winform 使用示例【第二集】

做一个所见即所得的Markdown编辑器

在本集中,使用了如下开源技术来方便的组建我们的“所见即所得Markdown编辑器”:

  • bootstrap
  • codeMirror
  • jquery
  • jquery.splitter.js
  • markdown-js
  • github-markdown.css

利用Nuget,获取上列的各种库不是难题。如效果图所示,我们可以方便的利用这些开源库来设计出心仪的页面。在此着重讲解网页前端和后台C#通信的技术。后面的文章里,凡是HTML、CSS和JS的内容我将称他们为“前端”、涉及C#编程的地方我会称他们为“后端”。

如图所示,软件将要与C#后端交互的几个地方有:

  • 代码编辑框
  • 新建文件按钮
  • 打开文件按钮
  • 保存文件按钮

在C#后端,建立HostEditor类来处理由前端发送回来的按钮事件。该类继承自基类JSObject,这个类负责与CEF的V8环境处理各种数据和对象。

 class HostEditor:JSObject
{
frmMain MainFrame;
internal HostEditor(frmMain main)
{
MainFrame = main; AddFunction("setCleanState").Execute += SetCleanState; AddFunction("newFile").Execute += NewFile; AddFunction("openFile").Execute += OpenFile; AddFunction("saveFile").Execute += SaveFile;
} private void SaveFile(object sender, Chromium.Remote.Event.CfrV8HandlerExecuteEventArgs e)
{
var contents = e.Arguments.FirstOrDefault(p => p.IsString);
var result = false;
if (contents != null)
{
result = MainFrame.SaveFile(contents.StringValue); } if (result)
{
e.SetReturnValue(this.GetCfrObject(new
{
success = true,
fileName = MainFrame.CurrentFile.Name
}));
}
else
{
e.SetReturnValue(this.GetCfrObject(new
{
success = false
}));
}
} private void OpenFile(object sender, Chromium.Remote.Event.CfrV8HandlerExecuteEventArgs e)
{
var contents = e.Arguments.FirstOrDefault(p => p.IsString);
string result = null;
if (contents != null)
{
result = MainFrame.OpenFile(contents.StringValue);
} if (!string.IsNullOrEmpty(result))
{
e.SetReturnValue(this.GetCfrObject(new
{
success = true,
fileName = MainFrame.CurrentFile.Name,
contents = result
})); }
else
{
e.SetReturnValue(this.GetCfrObject(new
{
success = false
}));
}
} private void NewFile(object sender, Chromium.Remote.Event.CfrV8HandlerExecuteEventArgs e)
{
var contents = e.Arguments.FirstOrDefault(p => p.IsString);
var result = false;
result = MainFrame.NewFile(contents.StringValue); e.SetReturnValue(CfrV8Value.CreateBool(result));
} private void SetCleanState(object sender, Chromium.Remote.Event.CfrV8HandlerExecuteEventArgs e)
{
if(e.Arguments.Length> && e.Arguments[].IsBool)
{
MainFrame.isClean = e.Arguments[].BoolValue;
}
}
}

在主窗体的构造函数中,将上面的HostEditor类注册到NanUI的JS环境中,并命名为hostEditor,这样在前端的JS中就可以调用hostEditor对象以及对象中内置的C#方法了:

GlobalObject.Add("hostEditor", new HostEditor(this));

在JS环境中hostEditor对象提供了以下几个方法来实现对当前代码编辑器里的内容进行新增、打开和保存的操作。

  • hostEditor.newFile(string)
  • hostEditor.openFile(string)
  • hostEditor.saveFile(string)
  • hostEditor.setCleanState(bool)

同时,将HostEditor中需要用到的新建文件、保存文件、打开文件等操作的方法放在主窗体中,方便前端JS调用。

        /// <summary>
/// 标记文档是否被修改
/// </summary>
internal bool isClean = true;
/// <summary>
/// 当前文档的存储路径,如果为空则说明该文档是新文档
/// </summary>
internal string currentFilePath = string.Empty; /// <summary>
/// 当前文档的FileInfo
/// </summary>
internal System.IO.FileInfo CurrentFile
{
get
{
return new System.IO.FileInfo(currentFilePath);
}
} /// <summary>
/// 获得一个标识当前文档是否为新建文档
/// </summary>
private bool IsNewFile
{
get
{
return string.IsNullOrEmpty(currentFilePath);
}
}
/// <summary>
/// 新建文件
/// </summary>
/// <param name="contents">当前文档中的内容</param>
/// <returns>如果新建成功则返回true</returns>
internal bool NewFile(string contents)
{
var continueFlag = true; if (!isClean)
{
var ret = MessageBox.Show(this, "文件已经更改,是否保存下先?", "提示", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (ret == DialogResult.Yes)
{
if (!SaveFile(contents))
{
continueFlag = false;
}
}
else if (ret == DialogResult.Cancel)
{
continueFlag = false;
} } if (!continueFlag)
{
return false;
} currentFilePath = null;
isClean = true; return true;
}
/// <summary>
/// 打开文档
/// </summary>
/// <param name="contents">当前文档中的内容</param>
/// <returns>如果新建成功则返回打开文档的内容</returns>
internal string OpenFile(string contents)
{
var continueFlag = true;
if (!isClean)
{
var ret = MessageBox.Show(this, "文件已经更改,是否保存下先?", "提示", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (ret == DialogResult.Yes)
{
if (!SaveFile(contents))
{
continueFlag = false;
}
}
else if (ret == DialogResult.Cancel)
{
continueFlag = false;
} } if (!continueFlag)
{
return null;
} var content = string.Empty; var openDialog = new OpenFileDialog()
{
AddExtension = true,
Filter = "Markdown文件|*.md"
}; if (openDialog.ShowDialog() == DialogResult.OK)
{
currentFilePath = openDialog.FileName; var fileInfo = new System.IO.FileInfo(currentFilePath); content = System.IO.File.ReadAllText(fileInfo.FullName); }
else
{
content = null;
} return content; }
/// <summary>
/// 保存文档
/// </summary>
/// <param name="contents">当前文档中的内容</param>
/// <returns>如果保存成功则返回true</returns>
internal bool SaveFile(string contents) { if (!IsNewFile) {
if (isClean) return true; System.IO.File.WriteAllText(currentFilePath, contents, Encoding.UTF8);
isClean = true;
return true;
} var saveFileDialog = new SaveFileDialog()
{
AddExtension = true,
Filter = "Markdown文件|*.md",
OverwritePrompt = true
}; if (saveFileDialog.ShowDialog(this) == DialogResult.OK)
{
currentFilePath = saveFileDialog.FileName; System.IO.File.WriteAllText(currentFilePath, contents, Encoding.UTF8); isClean = true; return true;
} return false; }

如此这般,一个所见即所得的Markdown编辑器就制作完成了。有了这个小工具编辑GitHub的README文档就不会那么痛苦了。有兴趣的朋友可以自行到GitHub下载代码来把玩。

那么,NanUI的第二集示例就这么讲完了。最后还是欢迎大家留言,或者进群讨论。当然能在github够提供pull request是最好的。

附件

MarkdownDotNet.zip - 编译好的Markdown编辑器,欢迎下载体验,代码已上传到GitHub


NanUI for .NET Winform系列目录


经过了这一个多星期的调整与修复,NanUI for .NET Winform的稳定版已经发布。应广大群友的要求,现已将NanUI的全部代码开源。

GitHub: https://github.com/NetDimension/NanUI

Release: https://github.com/NetDimension/NanUI/releases


如果你喜欢NanUI项目,你可以参与到NanUI的开发中来,当然你也可以更直接了当的支持我的工作,使用支付宝或微信扫描下面二维码请我喝一杯热腾腾的咖啡。

支付宝转账

微信转账


另外,打个广告,承接NanUI界面设计与接口开发(收费)。

案例展示

某聊天应用

某公司内部办公系统

NanUI for Winform 使用示例【第二集】——做一个所见即所得的Markdown编辑器的更多相关文章

  1. NanUI for Winform 使用示例【第一集】——山寨个代码编辑器

    NanUI for Winform从昨天写博客发布到现在获得了和多朋友的关注,首先感谢大家的关注和支持!请看昨天本人的博文<NanUI for Winform发布,让Winform界面设计拥有无 ...

  2. '用Roslynpad做一个轻量级的C#编辑器'

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:'用Roslynpad做一个轻量级的C#编辑器'.

  3. Winform窗体用对象数组做一个小项目

    首先我我们看一下需求:我们要做的是显示员工信息,实现项目经理给员工评分的功能! 首先项目经理是评分的人所以没有用,因为我们自己写,评分的就是我们自己.所以我们要做的是先在vs也就是我们的环境里建一个项 ...

  4. 使用Vue自己做一个简单的MarkDown在线编辑器

    1.首先要下载mark组件. npm install marked --save 2.在Vcontent.vue中简单写一些样式. <template> <div class=&qu ...

  5. 做一个所见即所得的CSS效果

    style 也是标签(在非ie内核的浏览器中支持),我们将style设置成 contenteditable的时候,那么那的内容就可以编辑了.仔细的体验下,如果我们将背景修改成红色的.那么只要书写完,立 ...

  6. NanUI for Winform发布,让Winform界面设计拥有无限可能

    如今,尽管WPF.UWP大行其道,大有把Winform打残干废的趋势.但是还是有那么一波顽固不化的老家伙们固守着Winform,其中就包括我. 好吧,既然都说Winform做得软件不如WPF界面美观效 ...

  7. Windows Phone开发(44):推送通知第二集——磁贴通知

    原文:Windows Phone开发(44):推送通知第二集--磁贴通知 前面我们说了第一个类型--Toast通知,这玩意儿不知大家是不是觉得很新鲜,以前玩.NET编程应该没接触过吧? 其实这东西绝对 ...

  8. SpringBoot第二集:注解与配置(2020最新最易懂)

    2020最新SpringBoot第二集:基础注解/基础配置(2020最新最易懂) 一.Eclipse安装SpringBoot插件 Eclipse实现SpringBoot开发,为便于项目的快速构建,需要 ...

  9. PB中用oracle的存储过程返回记录集做数据源来生成数据窗口,PB会找不到此存储过程及不能正常识别存储过程的参数问题(转)

    (转)在PB中用oracle的存储过程返回记录集做数据源来生成数据窗口 首先oracle的存储过程写法与MSSQL不一样,差别比较大. 如果是返回数据集的存储过程则需要利用oracle的包来定义游标. ...

随机推荐

  1. Senparc.Weixin.MP SDK 微信公众平台开发教程(十):多客服接口说明

    微信官方的多客服接口原理是通过用户发送的信息,开发者服务器返回一条指定类型的响应信息,使用户的对话状态切换到官方的多客服状态(持续一段时间),这段时间内用户发送的所有信息都不会到达开发者的服务器,而是 ...

  2. Java-接口练习1

    1.(1)编写一个接口ShapePara,要求: 接口中的方法: int getArea():获得图形的面积.int getCircumference():获得图形的周长 (2)编写一个圆类Circl ...

  3. Atitit  深入理解命名空间namespace  java c# php js

    Atitit  深入理解命名空间namespace  java c# php js 1.1. Namespace还是package1 1.2. import同时解决了令人头疼的include1 1.3 ...

  4. 发布iOS应用程序到苹果APP STORE完整流程

    参考:http://blog.csdn.net/mad1989/article/details/8167529(xcode APP 打包以及提交apple审核详细流程(新版本更新提交审核)) http ...

  5. python学习 操作mysql 环境搭建

    MySqlDB官网只支持Python3.4,这里Python3.5使用第三方库PyMysql连接Mysql数据库. 环境: window7.python3.5 下载PyMysql库:https://p ...

  6. SQLServer性能分析

    SQLServer性能分析 当数据库出现性能问题,应用出现运行缓慢的时候,下面这个东东能让你如获至宝 create table #sp_who2 ( SPID int ,status varchar( ...

  7. django获取指定列的数据

    django获取指定列的数据 model一般都是有多个属性的,但是很多时候我们又只需要查询特定的某一个,这个时候可以用到values和values_list [values()](https://do ...

  8. LigerUI学习使用

    LigerUI有如下主要特点: 使用简单,轻量级 控件实用性强,功能覆盖面大,可以解决大部分企业信息应用的设计场景 快速开发,使用LigerUI可以比传统开发减少极大的代码量 易扩展,包括默认参数.表 ...

  9. 05-Vue入门系列之Vue实例详解与生命周期

    Vue的实例是Vue框架的入口,其实也就是前端的ViewModel,它包含了页面中的业务逻辑处理.数据模型等,当然它也有自己的一系列的生命周期的事件钩子,辅助我们进行对整个Vue实例生成.编译.挂着. ...

  10. How does Spring @Transactional Really Work?--转

    原文地址:http://blog.jhades.org/how-does-spring-transactional-really-work/ In this post we will do a dee ...