C#生成CHM文件(应用篇)之代码库编辑器(2)
2010-10-19 07:34
453 查看
在上一篇文章中,我大致介绍了代码编辑器里面的一些主要功能和大致实现方法,从这篇文章开始,我将会将里面涉及到的一些技术跟大家分享下。
更新下程序 AlexisEditor下载
看下程序的界面,有菜单里、工具栏,还有几个可以悬停的面板
程序的Soultion , 可以看到有三个项目,一个WinForm项目及两个类库项目,增加类库项目是为了更好的实现代码分离。
下面的两张图是主项目AlexisEditor的类关系图:
在来看看ChmHelper项目的类关系图(这张图会在下面反复涉及)
Viusal Studio风格的界面的实现
在上一篇文章中有介绍到Viusal Studio风格的界面,它的实现很简单,由上图我们看到有许多Form是继承自BaseDockForm的,而BaseDockForm是继承自DockContent的。
实现步骤如下:
添加 WeifenLuo.WinFormsUI.Docking.dll引用,新建BaseForm继承自WeifenLuo.WinFormsUI.Docking.DockContent。
在主界面中放置一个DockPanel,设置它的Dock属性为Fill,然后在主界面中使用如下代码即可
public MainForm()
{
InitializeComponent();
frmIndex.Show(dockPanel);//显示目录窗体
frmIndex.DockTo(dockPanel, DockStyle.Left);
}
这样目录窗体就可以自动靠左显示,并可以自动隐藏。其他的窗体可以类似实现。
目录树的实现
上篇文章中讲到使用xml存储目录,那么这个xml是什么样的格式呢?AlexisEditor的目录树如下:
<CHMDocument Title="帮助文档">
<Items>
<Node Name="但是使用" Local="E:\WorkSpace\projects\AlexisEditor\AlexisEditor\bin\Debug\html_files\129317762488604234.htm" ImageNumber="1" KeyWords="" />
<Node Name="aa" Local="E:\WorkSpace\projects\AlexisEditor\AlexisEditor\bin\Debug\html_files\129317940192503066.htm" ImageNumber="1" KeyWords="" />
<Node Name="新建文件夹" Local="" ImageNumber="0" KeyWords="">
<Items>
<Node Name="aa" Local="E:\WorkSpace\projects\AlexisEditor\AlexisEditor\bin\Debug\html_files\129317940469098887.htm" ImageNumber="1" KeyWords="aaa" />
</Items>
</Node>
</Items>
</CHMDocument>
根节点是CHMDocument ,如果几点有<Items>子节点,表示该节点是父节点。
每个节点有这样的属性,Name表示文章的标题,Local表示文章的实际路径,ImageNumber表示几点的图片索引,KeyWords表示文章中的关键字。
如果该节点有子节点,则子节点也是这样的,当然父节点的Local、KeyWords为空。
这样的节点对应着类CHMNode,从类关系图中可以看到还有一个Nodes属性,它表示节点的子节点的集合。它是类CHMNodeList的实例,CHMNodeList继承自CollectionBase,并重写了一些集合的主要的方法。
CHMDocument类
CHMDocument类是ChmHelper中最重要的类,它表示当前的电子书,并且负责将书籍编译为CHM电子书的重任。下面着重来看它是怎么实现的,从上述的关系图中看到它有许多的方法、属性和字段。下面分别介绍:
CHMDocument类之属性
FileName表示CHM文件名,Nodes表示电子书除了根节点以外的节点集合,OutPutText表示在生成CHM电子书的编译信息,Title表示CHM的标题
CHMDocument类之字段
streamWriter:以流实现写入文件的类的实例,strHhp、strHhc、strHhk分别是临时生成的hhp、hhc、hhk文件的文件名,默认为alexisEditor,至于config他是静态类XBookConfig类的实例,用来实现一些配置信息,如编译器的路径,是否删除临时文件等。
CHMDocument类之方法
下图是CHMDocument类的主要方法及一些简单说明
先来看加载方法及其调用的方法
Name及Local写入到hhc文件中及hhk(索引文件中),两个主要的方法代码如下:
//递归实现将nodes写入hhc文件中
ok,至此已经讲了
如何创建Viusl Studio风格的窗体程序?
【让要悬停的窗体继承自DockContent,在调用窗体添加DockPanel,实例化悬停窗体,调DockTo方法】
PS:说明下,如何在ToolBox中添加DockPanel图标==》右击工具箱(ToolBox),选择“选择项...”,添加WeifenLuo.WinFormsUI.Docking.dll引用即可
以及目录是怎么通过xml实现的?
【使用xml存储书籍目录信息,使用类与xml、书籍对应,使用递归的方法获取树的节点】
当然目录树中还有许多其他的问题,今天将的只是类库里面的东西,不过万变不离其中,前台基本上都市调用这些代码的。
看了这篇文章后,大家可以尝试建立个Visual Studio风格的窗体、ChmHelper类库项目的大体(具体实现个随喜好),如果关于以上两点大家还有什么不明白的,
可以留言或者发邮件给我,我会尽快回答的。
再次PS下,如果觉得好的话,请推荐。另:求visual studio编译项目的图标(BMP格式,16*16)
更新下程序 AlexisEditor下载
看下程序的界面,有菜单里、工具栏,还有几个可以悬停的面板
程序的Soultion , 可以看到有三个项目,一个WinForm项目及两个类库项目,增加类库项目是为了更好的实现代码分离。
下面的两张图是主项目AlexisEditor的类关系图:
在来看看ChmHelper项目的类关系图(这张图会在下面反复涉及)
Viusal Studio风格的界面的实现
在上一篇文章中有介绍到Viusal Studio风格的界面,它的实现很简单,由上图我们看到有许多Form是继承自BaseDockForm的,而BaseDockForm是继承自DockContent的。
实现步骤如下:
添加 WeifenLuo.WinFormsUI.Docking.dll引用,新建BaseForm继承自WeifenLuo.WinFormsUI.Docking.DockContent。
在主界面中放置一个DockPanel,设置它的Dock属性为Fill,然后在主界面中使用如下代码即可
public MainForm()
{
InitializeComponent();
frmIndex.Show(dockPanel);//显示目录窗体
frmIndex.DockTo(dockPanel, DockStyle.Left);
}
这样目录窗体就可以自动靠左显示,并可以自动隐藏。其他的窗体可以类似实现。
目录树的实现
上篇文章中讲到使用xml存储目录,那么这个xml是什么样的格式呢?AlexisEditor的目录树如下:
<CHMDocument Title="帮助文档">
<Items>
<Node Name="但是使用" Local="E:\WorkSpace\projects\AlexisEditor\AlexisEditor\bin\Debug\html_files\129317762488604234.htm" ImageNumber="1" KeyWords="" />
<Node Name="aa" Local="E:\WorkSpace\projects\AlexisEditor\AlexisEditor\bin\Debug\html_files\129317940192503066.htm" ImageNumber="1" KeyWords="" />
<Node Name="新建文件夹" Local="" ImageNumber="0" KeyWords="">
<Items>
<Node Name="aa" Local="E:\WorkSpace\projects\AlexisEditor\AlexisEditor\bin\Debug\html_files\129317940469098887.htm" ImageNumber="1" KeyWords="aaa" />
</Items>
</Node>
</Items>
</CHMDocument>
根节点是CHMDocument ,如果几点有<Items>子节点,表示该节点是父节点。
每个节点有这样的属性,Name表示文章的标题,Local表示文章的实际路径,ImageNumber表示几点的图片索引,KeyWords表示文章中的关键字。
如果该节点有子节点,则子节点也是这样的,当然父节点的Local、KeyWords为空。
这样的节点对应着类CHMNode,从类关系图中可以看到还有一个Nodes属性,它表示节点的子节点的集合。它是类CHMNodeList的实例,CHMNodeList继承自CollectionBase,并重写了一些集合的主要的方法。
CHMDocument类
CHMDocument类是ChmHelper中最重要的类,它表示当前的电子书,并且负责将书籍编译为CHM电子书的重任。下面着重来看它是怎么实现的,从上述的关系图中看到它有许多的方法、属性和字段。下面分别介绍:
CHMDocument类之属性
FileName表示CHM文件名,Nodes表示电子书除了根节点以外的节点集合,OutPutText表示在生成CHM电子书的编译信息,Title表示CHM的标题
CHMDocument类之字段
streamWriter:以流实现写入文件的类的实例,strHhp、strHhc、strHhk分别是临时生成的hhp、hhc、hhk文件的文件名,默认为alexisEditor,至于config他是静态类XBookConfig类的实例,用来实现一些配置信息,如编译器的路径,是否删除临时文件等。
CHMDocument类之方法
下图是CHMDocument类的主要方法及一些简单说明
先来看加载方法及其调用的方法
public void Load(string filename) { System.Xml.XmlDocument doc = new System.Xml.XmlDocument(); doc.Load(filename); FromXML(doc.DocumentElement); }和
private void FromXML(System.Xml.XmlElement RootElement) { //this.defaultPage = RootElement.GetAttribute("DefaultTopic"); this._title = RootElement.GetAttribute("Title");//标题 nodeList.Clear(); foreach (System.Xml.XmlNode node in RootElement.ChildNodes) { if (node.Name == "Items") { NodesFromXML(nodeList, (System.Xml.XmlElement)node); } } } 和 private void NodesFromXML(CHMNodeList nodes, System.Xml.XmlElement RootElement) { foreach (System.Xml.XmlNode node in RootElement.ChildNodes) { if (node.Name == "Node") { System.Xml.XmlElement element = (System.Xml.XmlElement)node; CHMNode NewNode = new CHMNode(); NewNode.Name = element.GetAttribute("Name"); NewNode.Local = element.GetAttribute("Local"); NewNode.ImageNo = element.GetAttribute("ImageNumber"); NewNode.KeyWords = element.GetAttribute("KeyWords"); nodes.Add(NewNode); foreach (System.Xml.XmlNode node2 in element.ChildNodes) { if (node2.Name == "Items") { NodesFromXML(NewNode.Nodes, (System.Xml.XmlElement)node2); } } } } } 注意NodesFromXML 方法是递归的方法,大家可以仔细琢磨下这些代码,保存方法其实是类似的,不同的是将节点保存到xml中,代码如下: public void Save(string filename) { System.Xml.XmlDocument doc = new System.Xml.XmlDocument(); doc.AppendChild(doc.CreateElement("CHMDocument")); ToXML(doc.DocumentElement); doc.Save(filename); _fileName = filename; }
private void ToXML(System.Xml.XmlElement RootElement) { //RootElement.SetAttribute("DefaultTopic", this.strDefaultTopic); RootElement.SetAttribute("Title", this._title); System.Xml.XmlElement element = RootElement.OwnerDocument.CreateElement("Items"); RootElement.AppendChild(element); NodesToXML(nodeList, element); }
//nodes保存为xml private void NodesToXML(CHMNodeList nodes, System.Xml.XmlElement RootElement) { System.Xml.XmlDocument doc = RootElement.OwnerDocument; foreach (CHMNode node in nodes) { System.Xml.XmlElement NodeElement = doc.CreateElement("Node"); NodeElement.SetAttribute("Name", node.Name); NodeElement.SetAttribute("Local", node.Local); NodeElement.SetAttribute("ImageNumber", node.ImageNo); NodeElement.SetAttribute("KeyWords", node.KeyWords); RootElement.AppendChild(NodeElement); if (node.Nodes != null && node.Nodes.Count > 0) { System.Xml.XmlElement ItemsElement = doc.CreateElement("Items"); NodeElement.AppendChild(ItemsElement); NodesToXML(node.Nodes, ItemsElement); } } }接下来看下编译方法是怎么实现,具体的代码就不贴了,前面的文章中《C#生成CHM文件(入门篇)》中就有涉及,这里要提到的就是里面的递归算法,即分别将树中的
Name及Local写入到hhc文件中及hhk(索引文件中),两个主要的方法代码如下:
//递归实现将nodes写入hhc文件中
private void NodesHhc(CHMNodeList nodeList) { if (nodeList.Count == 0 || nodeList == null) return; streamWriter.WriteLine(" <UL>"); foreach (CHMNode node in nodeList) { if (node.Nodes != null && node.Nodes.Count > 0)//如果是父节点 { streamWriter.WriteLine(" <LI><OBJECT type=\"text/sitemap\">"); streamWriter.WriteLine(" <param name=\"Name\" value=\"" + node.Name + "\">"); streamWriter.WriteLine(" </OBJECT>"); NodesHhc(node.Nodes); } else//如果是子节点 { streamWriter.WriteLine(" <LI><OBJECT type=\"text/sitemap\">"); streamWriter.WriteLine(" <param name=\"Name\" value=\"" + node.Name + "\">"); streamWriter.WriteLine(" <param name=\"Local\" value=\"" + node.Local + "\">"); streamWriter.WriteLine(" </OBJECT>"); } } streamWriter.WriteLine(" </UL>"); } 及 //递归写hhp中的Files private void NodesHhp(CHMNodeList nodeList) { if (nodeList == null || nodeList.Count == 0) return; foreach (CHMNode node in nodeList) { if (node.Nodes == null || node.Nodes.Count == 0) { streamWriter.WriteLine(node.Local); } else { NodesHhp(node.Nodes); } } } 至于获取文件的相对路径和绝对路径的方法相信大家都会写,这里就不介绍了。
ok,至此已经讲了
如何创建Viusl Studio风格的窗体程序?
【让要悬停的窗体继承自DockContent,在调用窗体添加DockPanel,实例化悬停窗体,调DockTo方法】
PS:说明下,如何在ToolBox中添加DockPanel图标==》右击工具箱(ToolBox),选择“选择项...”,添加WeifenLuo.WinFormsUI.Docking.dll引用即可
以及目录是怎么通过xml实现的?
【使用xml存储书籍目录信息,使用类与xml、书籍对应,使用递归的方法获取树的节点】
当然目录树中还有许多其他的问题,今天将的只是类库里面的东西,不过万变不离其中,前台基本上都市调用这些代码的。
看了这篇文章后,大家可以尝试建立个Visual Studio风格的窗体、ChmHelper类库项目的大体(具体实现个随喜好),如果关于以上两点大家还有什么不明白的,
可以留言或者发邮件给我,我会尽快回答的。
再次PS下,如果觉得好的话,请推荐。另:求visual studio编译项目的图标(BMP格式,16*16)
相关文章推荐
- C#生成CHM文件(应用篇)之代码库编辑器(1)
- C#生成CHM文件(应用篇)之代码库编辑器(4)【附程序最终版下载】
- C#生成CHM文件(应用篇)之代码库编辑器(1)
- C#生成CHM文件(应用篇)之代码库编辑器(3)【附源代码下载】
- C#生成CHM文件(应用篇)之代码库编辑器(4)【附程序最终版下载】
- C#生成CHM文件(应用篇)之代码库编辑器(3)【附源代码下载】
- C#生成CHM文件(应用篇)之代码库编辑器(5)【总结、程序、源代码】
- C#生成CHM文件(应用篇)之代码库编辑器(2)
- C#生成CHM文件(应用篇)之代码库编辑器(5)【总结、程序、源代码】
- C#生成CHM文件(应用篇)
- C#生成CHM文件(应用篇)
- C#生成CHM文件(应用篇)
- C#生成CHM文件(入门篇)
- C#编程生成的Word2007版本的文件如何兼容Word2003?(通过代码将docx文件转存为doc文件)
- 根据现有C#代码文件生成扩展代码文件的想法
- C#代码生成XML文件
- 用C#代码生成一个简单的PDF文件
- C#生成CHM文件(中级篇)
- C# 解析 Excel 并且生成 Csv 文件代码分析
- 用C#代码生成一个简单的PDF文件(转)