使用 .NET WinForm 开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

直接切入正题,这是我09年到11年左右业余时间编写的项目,最初的想法很简单,做一个能拖拖拽拽就直接生成应用程序的工具,不用写代码,把能想到的业务操作全部封装起来,通过配置的方式把这些业务操作组织起来运行。

项目的核心功能已经基本实现,但12年之后我基本停止了这方面的开发,现在翻出来在这里写出来想和大家交流一下。

 

鉴于篇幅和精力的原因,请原谅我这篇博文对于技术实现的具体细节谈的不是很多,只能算是一个概述。对业务的说明也不多,我想大家都是技术流,应该一看就明白。

写这个项目的时间是五六年前,现在回过头去看,有很多不足之处,设计上的,技术上的都有,加上当时技术力有限,不足之处还请指正,谢谢。

后续是否会写一个系列的博文详细的分析讲解实现方法,我暂时也没有想好,主要是没有太多时间,我现在基本又回到了当初每天只睡四五个小时的状态。

如果此篇博文有点儿价值,给个推荐呗 ^_^ 

 

项目使用了 .Net Framework 3.5 开发,分为两大块: IDE 和 运行时(解析器)

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

IDE中开发的项目在打包后生成 zip 格式的包,解析器通过读取 zip 包实时解析运行,有点类似中间语言的概念,但我这里生成的 zip 包中主要以 xml 文件为主,通过 xml 文件对项目的 UI,业务,数据结构 进行描述。

 

到此可以看出,运行时本身并不一定是 .Net 或 WinForm 的,而是可以使用任何平台或语言实现,只要读取 zip 文件和 xml 文件并解析即可。

事实上我自己实现的默认运行时也不是 WinForm,而是用了 Silverlight。

 

再简单说说 IDE 的设计思路,几个主要的设计目标如下:

 

1.像 Visual Studio 一样

  有可视化的环境,拖拖拽拽界面就出来了。

2.模块化设计

  功能模块全部独立,解耦,以插件的形式存在于主程序(宿主)中。

2.不要写代码,业务通过界面,向导进行配置

  拖一个按钮上去,想要单击时做一件事情,就先把按钮拖上去,然后设置这个按钮的事件序列,配置对应的事件。

3.把事件这个概念抽象并封装起来

  如“保存数据”这个事件,配置好数据的来源,如窗体上的数据,或系统数据,再配置好要保存的目标,某种数据实体,即可,这个事件被添加到某个事件序列,如按钮的单击事件序列中,项目被运行时解析时,就会按钮这个逻辑执行。

4.对数据操作要有一定的自由度

  除了基本的向导式配置以外,要能满足特殊需求,比如支持自定义 sql 语句。但是自定义 sql 语句怎样与数据源,目标交互呢?我设计了一种简单的表达方法,如 UPDATE FROM [User] SET [Name] = {FormElement.txtName} WHERE [Id]={System.UserId}

5.对数据库数据表的操作怎样交互

  就是将其抽象为“数据实体”,数据实体也在 IDE 中由用户自己定义,定义的过程类似于 SqlServer,定义好数据实体以后,在 IDE 中进行设计时,通过数据实体来抽象对数据库、表的操作,在打包项目时,可以根据定义的数据实体,生成多种数据库,如 SqlServer,Mysql 等。

6.资源文件的管理

  在项目中必然要引用到外部资源,这部分外部资源,怎样引入,管理,打包呢?我在 IDE 中设计了独立的资源管理器,在 IDE 中设计 UI 时,通过资源管理器引用资源,打包时,将资源打包到 zip 文件中。

7.打包前的静态编译检查

  类似于我们在 Visual Studio 中写程序,编译时如果有错误就会出现警告或错误提示。在这个 IDE 中,也必须有同样的功能。当引用的数据实体被删除,数据项不存在,引用的资源文件不存在,以及事件配置中一些问题出现时,能够实时,并在打包项目时指出这些错误的具体位置。

8.支持嵌入脚本

  能够在事件序列中添加自定义脚本,支持在运行时动态解析或者调用某种脚本语言。此功能有所设计,但并未开发

9.支持插件

  此处插件支持指的是 IDE 层面能够支持插件,类似 Visaul Studio 或者 Eclipse 的插件机制,我当时使用的是 .NET 管线技术(很冷门),实现了相关DEMO,但是没有集成到IDE中。

10.IDE界面支持多国语言

  目前IDE完整支持多国语言,所有文本均使用了资源,但是我没有直接使用资源文件,而是将其强类型化了,具体实现方式下文详述。

 

在设计开发这个 IDE 的早期,我并没有给自己设定如此详细的目标,现在写其实更多的是回顾和总结。

 

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

 

在这个项目中,大量使用了 GDI+ 绘图,说复杂,给你调用的接口也就那么多,说简单,用 GDI+ 自己写一个功能完备的 WinForm 控件,分分钟教你重新做人。在这个项目中,几乎所有的界面元素都是我自己用 GDI+ 绘制的,使用的第三方控件不多。后面我会写一些这方面的感想。

 

下面罗列一些技术难点和主要功能点,有些细节可能没有试着做过都不会意识到那是个问题。

 

1.工具栏按钮/右键菜单的状态控制

  就是控制状态栏上按钮可用不可用,可见不可见,绝大多数时候这不是个问题,但是作为一个 IDE,工具栏上的各种按钮非常多,且按钮的状态和当前设计器中的选中元素个数,选中元素类型,甚至选中元素自身的状态等等相关,还有些按钮是特定控件或元素提供的,怎样统一控制这些按钮的状态?

黄色背景部分是动态挂载上去的,状态的控制在后文中说明。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

 

此处右键菜单指的是窗体设计器中的右键菜单,在窗体设计器中,右键菜单比较复杂,不同控件的右键菜单有所不同,有共通的项目,有特殊的项目,以及状态是不是灰掉可能和控件本身的某些因素有关,但右键菜单本身是不可能通过处于设计状态的控件自身提供的,所以此处如何把控件特有的菜单项挂载上去,又怎样控制它们的状态?注意设计器本身和用来设计的控件是解耦合的。

注意这个例子,右键 DataGrid 产生的右键菜单中存在“添加列” 和“编辑列”两个特殊的项目。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

此处当我选中 DataGrid 时,属性网格下方也会出现这两个项目,这里先提一个关键概念,叫做“谓词”,这是一个 DesignSurface 中的概念,后文再详述。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

 

此处实际上我实现了一个独立的菜单(包括工具栏项目)的管理器,并非直接创建 MenuItem 之类的实例去使用,这个管理器也是独立于业务进行设计的,对菜单项的各种状态,行为都进行了抽象与封装。在管理器层面统一调度这些菜单项,通过一定的机制使菜单项的状态与业务状态关联起来,不允许外部代码直接修改菜单项的状态,整套机制本身,与菜单项在UI层面的实现也是无关解耦的,最终生成可见菜单项时,才会生成特定的控件,如 MenuItem,也可以换成其它任何菜单项控件,不影响管理器的功能与逻辑。

我记得当时我研究了几个IDE的设计细节,包括  Visual Studio,应该都采用了类似的机制,好吧我承认是我研究之后借鉴了它们的机制。

这个问题我放在首位,是我意识到这个问题在大型软件中,真的是个很大的问题,我现在参与开发的一款电气化CAD软件中,就存在这个问题,但是他们早期并未意识到这个问题,也谈不上能很好的解决,几千个菜单项,工具栏按钮项,直接硬编码,对他们的状态控制也谈不上成体系,就是粗暴的硬编码,现在的维护,修改,调整都异常痛苦。

 

2.窗体设计器

  最初我是自己用 GDI+ 写了一个简单的设计器模型,支持拖拽,绘制,动态对齐等等功能,但是越往后越复杂,比如绘制一个 DataGrid,你不能光是一个框框,你要自己去绘制它的列,列头,如果要绘制一个图片框,你就要自己去绘制它的图片内容,要考虑图片的缩放方式等等细节,如果要一条道走到黑完全自己实现,成本将非常高昂。

先看看早期直接使用 GDI+ 实现的效果:

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

 

下面是直接使用微软 DesignSurface 效果:

和 Visual Studio 效果一样,不过这里需要注意的是 DesignSurface 仅仅也只是提供了基本的窗体设计能力(图中右侧部分),比我上面GDI+自己写的功能多不了多少,但是不用自己绘制控件的外观,其它辅助功能都是需要自行开发的。

这里要注意的一点是窗体设计器中 允许被设计 的控件 们,是与设计器本身,与IDE解耦的,是完全独立实现的,后期添加新控件,修改控件都与IDE无关,这个地方的难点毅然是解耦合,各种解耦合。

左侧的属性列表是自行开发的,.Net Framework 中确实提供了 PropertyGrid 控件,但是对于高阶开发此处并不适用,有很多制限,下文详述。

 

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

 

3.工具箱

  工具箱本身是独立实现的,不依赖其所处的窗体设计器,同时它自身所承载的控件,也是动态载入的,后期允许第三方插件挂载控件到工具箱中。

  这个地方需要注意的不多,一个是动态载入控件,另一个就是在和窗体设计器交互的时候,比如我拖一个控件到设计器上,这里是需要对接 DesignSurface 的。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

 

4.属性网格(PropertyGrid)

.Net Framework 中提供了 PropertyGrid 控件,可以实现对对象实例的属性编辑功能,但是难于扩展与自定义,我此处需要个性化定制的地方比较多,所以选择自己实现一个。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

主要实现了以下功能

1)对于单个对象实例,列出它的属性(Property,下同),以及属性的值,如果属性值与默认值不同,能够粗体显示。

2)对于特殊的属性,提供对应的扩展编辑器,如颜色属性,在点击后应该提供一个颜色选择器。且这些扩展编辑器,是与属性网格本身解偶的。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

3)如果同时设置了多个不同类型(Type)的对象实例,例如在窗体设计器中框选了多个控件,这个场景就复杂一些了;首先得到这些对象实例的类型(Type),抽取共通的属性,属性网格中仅显示共通属性,对于某个属性的值,如果所有对象实例的值是相同的,则显示,如果有所不同,则留空不显示。在设置了某个属性的值之后,能够将新值设置到这些对象实例中。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

 

 

5.撤销重做引擎

这里可以用的上“引擎”二字,因为确实比较复杂,我们先将这个问题简化,可以简单理解为对“对象”属性变化的跟踪,可以撤销这些变化,也可以重做这些变化,可以任意步骤的操作。

涉及到的问题和知识点很多,在 IDE 里对象状态的变化又被抽象为具体的“操作”,以及这些操作又要和设计器进行联动,有一定难度。

UI上的效果是直接使用 GDI+ 自定义的一个列表,并不是很复杂,其它能够直观看的界面UI不多,主要是代码了。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

 

6.事件及事件编辑器

上文中提到,要将常用的操作(事件)都封装起来,通过配置的方式来运行,大方向好像并不复杂,但是,怎么做呢?首先事件本身的抽象要独立,要与窗体设计解耦合,其次“事件”的定义应该允许由第三方插件扩展,甚至“触发时机”也应该允许由第三方插件进行扩展。以一个最简单的按钮为例:

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

看上去和普通编程中的事件机制没什么区别,是的,我们要做的是对其基本机制进行抽象化。例如:

1)触发时机应该与事件寄主解耦,甚至允许第三方插件挂载触发时机。

2)事件序列应该与触发时机解耦,事件序列中的事件定义,应该与以上机制解耦,甚至允许第三方插件扩展。

 

看看项目中实现的效果:

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

我们就以“为窗体元素加载数据”这个事件为例,看看现在的事件编辑器大概是什么模样。

这个事件支持“关联数据实体方式”和“执行 SQL 方式”。

切换到数据实体界面中,选一个数据实体,然后设置相关的数据项。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

这里就可以配置事件在执行时,从哪里取得数据,我们指定了从 用户 这个数据实体中选择数据,同时指定了一个条件,就是 用户的 Id 要等于 指定文本框中的值。

除了使用界面元素中的值作为条件,还可以使用系统数据,如:

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

 

对于选择特定的用户,比如这个 Id 怎样获取呢?只要在加载数据时,把 Id 绑定到一个隐藏的文本框中就可以了,加载数据时,可以读取它的值。

然后切换到载入界面

在载入界面中,指定我的数据取出来以后,加载到界面的哪些元素中。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

我们上文提到,希望对数据的操作有一定的自由度,那么在事件编辑器中,就允许直接定义 sql 语句,或者说 sql 语句的模板。

切换到 sql 界面后,首先可以通过 获取 sql 按钮自动根据前面的配置生成 sql,然后在此基础上进行调整,修改。

在 sql 编辑器中,可以通过 {Provider.Source} 的方式访问数据。

支持语法着色,支持智能提示。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

目前实现了两种 Provider,FormElement (窗体元素)和 System (系统),在智能提示中支持递进的提示。

所谓递进的提示是输入“{”之后自动给出 Provider,选择后进一步自动给出 Source 列表。

也可以在 “{Provider” 后输入“.” 则自动给出 Source 列表。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

智能提示用起来简单方便,看起来也很简单,貌似只是一个 Popup ,实则是一个不小的坑,这个功能困惑了我很久,记得当时到处找大神请教,除了高谈阔论的就是直接告诉我不知道,有个人也研究过 SharpDeveloper,告诉我这个问题深了,后来我又去翻 SharpDeveloper 的源代码,参考了它的实现,完成之后还是相当有成就感的。

 

对于事件序列的编辑,有两种方法,一种是在设计器中双击控件之后打开的事件序列编辑器

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

另一种方法是在窗体设计器中提供了以树形方式展示的事件序列,可以直接拖动改变事件的触发时机,或其在事件序列中的位置。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

 

事件在解析器中执行时,是按钮它所处事件序列中的顺序进行执行的。

 

目前实现的事件大概有十几个,基本的应用程序操作,数据交互等。

不再一一详细说明,因为事件本事是在解耦的情况下独立实现的,IDE并不依赖他们,所以未来扩展也很容易,可以说IDE和解析器是核心引擎,而这些事件定义,只是系统中的“业务”部分。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

 

7.集合编辑器

集合编辑器,就真的只是用来编辑对象集合的,支持对集合中对象实例的编辑,以及集合中元素顺序的调整,并且在与窗体设计器解耦合的基础上,与窗体设计器联动,能够从窗体设计器中的元素取得对象集合,同时与撤销/重做引擎对接,在编辑的过程中,提供撤销/重做的支持。

这个编辑器完成之后复用性比较强,在窗体设计器中有很多地方需要对集合进行编辑,行定义,列定义,元素定义之类。

一个典型的使用场景是在窗体设计器中,对 DataGrid 的列进行编辑。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

 

8.有效性检查

在窗体设计器中,能够对当前窗体中的各项设置,包含的事件进行有效性的检查。例如我在某个事件中设置了加载数据到 TextBox1 ,后来我删除了这个 TextBox1 ,那么就必须给出提示。

此处的主要难点应该在于解耦合,各种解耦合。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

 

9.IDE多国语言实现

  Visual Studio 自带的资源文件编辑器使用起来不是很方便,比如多国语言,是分开在多个资源文件编辑器窗口中编辑的,没有一一对应的显示语言文本,另外直接使用资源文件,使用的是通过 String 做参数的弱类型方式进行调用的,不能做静态编译时检查,也无法保证多语言相关编码的质量。所以这里我没有直接使用资源文件机制,而是进行了二次开发,我专门开发一个资源文件编辑器,提供一个一体化的界面同时编辑多国语言资源文件,使资源key同时和多个资源文件对应起来,同时支持导出excel,交给翻译翻译之后直接导回来,然后解析资源文件中的资源,生成一个统一的 ILanguage 接口,和不同的语言实现,如 class Chinese:ILanguage,class English:ILanguage,调用时,直接使用接口进行强类型调用,即将 Resource.GetString(“buttonText”) 变换为 _language.buttonText。

  另一方面,实现了一种将界面文本绑定到资源的机制,这一点在 WPF 下非常方便,在 WinForm 下就要自己动手了。通过特定字符串标记资源key,在运行时自动扫描窗体或其它容器控件,通过解析这些字符串自动查找对应的资源,将其替换。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

 

10.界面用户数据的验证

  目前几乎所有的开发平台都提供了比较友好的用户输入验证方案,在 WinForm 下也有,不过并不是很完善,使用起来限制比较多,功能也有限,不是很顺手。

  我自己开发了一套用于 WinForm 的用户界面数据验证功能。举个最简单的例子,我给文本框设置一个不允许空的属性,或者设置一个正则表达式,在我调用验证方法时,就能够对它进行有效性验证。方案非常简单,只是要花点心思把它实现好,各种控件都要支持,要解耦合,验证器要支持多种不同验证机制,验证结果如何向用户反馈等等。

  这套验证机制也同样实现在了运行时(解析器)当中。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

验证结果的反馈并不一定要用 MessageBox,可以很容易的改进为其它更友好的形式。

 

11.模块化设计

模块化,插件式的框架设计现在应该有很多现成的框架和设计方法,但是在当时,又是 WinForm 下,可以参考的资料非常少,大方向不复杂,但是做完善做细致,在当时对我来说有相当大的难度。当时唯一可以参考的是微软的 CAB 框架,但在当时来看,CAB 就已经是一个有些过时的框架了,使用起来有一些缺点和限制。

我在参考 CAB 的基础上在 WinForm 下实现了一套分解的非常细致的模块化开发框架,对软件的功能进行层层解耦,宿主程序与功能模块完全无关,而在我业务功能的设计上,IDE中的功能也实现了完全解耦,上文也多处提到了,窗体设计器与被设计的控件包解耦,事件机制与具体的事件定义解耦等等。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

 

 

 

其它功能点

其它功能点主要是指:数据实体定义,主菜单定义,枚举定义,资源管理,以及其它小功能等,下文先做个简单展示,暂不再做详细的说明。

 

1.欢迎界面

欢迎界面是内嵌了一个 HTML 页面,只是和 C# 代码有简单交互,例如单击链接会调用 C# 方法,并传入参数。

使用 HTML 的一个原因是希望欢迎界面比较漂亮,但是在 WinForm 下实现一个漂亮的,交互性强,维护性强的欢迎界面有一定难度,很浪费时间。

此处注意一个细节, URL 地址不是一个磁盘文件地址,而是一个自定义协议和路径的地址,这个需要自己实现,但是很简单。

年代久远,CSS 和图片可能遗失了,不太好看,见谅。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

 

2.数据实体定义

这块相对比较简单,没有复杂功能。

发布项目时可以根据数据实体定义自动生成数据库。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

 

也可以针对指定的数据实体生成脚本。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

 

3.枚举定义

界面很简单,生成数据库时,根据枚举定义向枚举表插入枚举数据。

但是有一个小细节是它和窗体设计器是有对接的,它是一个数据源的 Provider,可以在设计器中把控件中的值绑定到枚举。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

 

4.主菜单/工具栏定义

定义要生成的软件的主菜单和工具栏,运行时解析之后,根据自己的实现方式生成,可以是 Ribbon 的,也可以是传统的,或者其它方式。

菜单或工具栏项目支持事件,可以挂载事件序列。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

 

5.资源管理

实现一个资源管理器,目前只实现了对图片资源的管理。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

 

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

 

这里有点看点的是,我当时没有找到我觉得不错缩略图控件,于是只好自己实现一个。和 Windows 资源管理器功能一致,没有需要特殊说明的地方,只是自己从头实现一个不能说很难,但是真的很麻烦。借这个地方简单讲一下这个缩略浏览器的实现,可能有些朋友对 GDI+ 不是很了解。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

对于在 WinForm 下使用 GDI+ 绘制界面(自己实现一个控件),是比较原始的,想像一下给你一张白纸,和一些简单的绘图接口,画线,画圆,画矩形,其实没别的了。画一个圆角矩形?自己计算坐标系,通过画弧线和画直线画一个。显示一些文本?自己进行字体字号测量坐标系换算,如果涉及到文本换行,超长用省略号代替,都是比较麻烦的。

你要自己在 逻辑上 把握控件的不同状态,如选中,非选中,鼠标滑过等等,和WPF下预定义的状态组不同,WinForm 下这些状态是你要自己去把握的,状态切换时,你要自己根据状态进行重绘……

在绘制界面时,你只有一个从0,0开始的二维的平面坐标系,和它的尺寸。实现这样一个缩略图浏览器,缩略图的排版,布局,一行显示多少个,什么时候换行,选中非选中,鼠标框选,滚动条滚动都需要自己实现,包括鼠标框选时的框,也是需要自己用 GDI+ 绘制的,然后自己计算坐标系,判断哪些项目应该处于被选中状态。

这个控件的代码接近3000行。现在回过头去看,只觉得注释不够详细。

软件中大部分自己实现的控件,都采用了类似的架构进行设计:控件本身,布局管理器,呈现器,呈现器实现,主题。

 

6.生成数据库,生成项目

这里目前并不复杂,生成数据库根据数据实体定义生成即可,生成项目目前我直接使用了项目文件,因为我目前的项目文件格式就是 zip 包,内含 xml 文件。

附带产出是实现了一个简单的比较通用的向导功能。

使用 .NET WinForm  开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

 

7.其它控件的美化。

从上面的截图中能够看到我使用了相当多的自定义控件,或经过美化的 WinForm 自带控件,典型的几个除了上面的缩略图控件,还有IDE上面的主菜单(效果参考了 Paint.NET), DataGrid,重新实现的 ComboBox 等等,居然一步一步形成了一个自己的控件包。可惜技术更新换代日新月异,现在也基本用不上了。

 

IDE 部分现在回过头去看,貌似实际功能并不多,但是核心架构已经基本完整了,后续如果继续开发,基本相当于开发插件和添加新的功能包。 

其中绝大部分是从空白 class 硬写出来的,很多地方用现在的眼光去看,存在很大的过度设计问题。

 

解析器部分我是用 Silverlight 实现了一个,核心实现了,业务没有实现完整,可能是我现在的机器 Silverlight 版本有问题还是怎么回事没有运行起来,也不想去调试了,

并不复杂,只是解析 zip 包,xml文件,生成界面,事件处发时解析事件序列中的事件即可。

 

最后,如果你现在要做客户端软件,选择 WPF 吧,生产性非常高,功能非常完善与强大,如果你担心性能问题,我想说现在已经2015年了,不是2005年,如果你在开发中遇到了性能问题或其它问题,先从自身找原因。

专业程序员永远从自身找问题,业余程序员从平台从语言找问题。

 

后记:

最后想写一点点个人的感想与反思。我在开发这个软件的过程中,犯了许多的错误,这些错误未必是技术上的,但都是严重错误。

首当其冲:闭门造车。活在自己的技术宅世界里,从来不去想,也不愿意去想这个东西有多少实际价值,谁会去用它,到了后来,我明明潜意识里知道这个软件没有太大市场价值,就是不愿意去想这个问题,一门心思去开发。我记得那两年我随身带的手机里,记满了关于这个软件的想法和一些问题的实现思路。我在路上想到某个解决方案或者有什么想法,就立马掏出手机记录,怕回去就会忘记。有一个冬天住的地方没有空调,非常冷,写代码一直写一直写,两个手冻青了,就自己用热水瓶子捂捂继续写,那段时间每到周末就特别高兴,因为有2个完整的工作日可以利用了,不用单纯靠晚上的时间去写,很长一段时间我每天晚上我都只能睡四五个小时,个别时候还没睡着,天就蒙蒙亮了。但是这么辛苦的意义是什么呢?我当时没有认真的思考。

第二:目标非常的不明确。看上去有目标,我要做一个什么什么样的东西,但是太宏大,太宽泛,太遥远。没有认真的考量我要的到底是个什么,所以完全没有详细的计划,里程碑什么都没有。

第三:缺少与外界沟通。这个沟通除了技术,更多的是市场对技术的需求到底是什么,如果回到当初,我会抽自己一巴掌,你睁开眼睛,走出去看看别人的世界好吗!做技术不是高新技术行业,更多的是服务业,我们需要利用手中的技术去为他人服务,这是技术存在的意义。

第四:不懂快速迭代,最小可用集。这个概念现在应该大家都知道了,在当年好像并不是很流行,也可能和我长期做企业级开发有关系,项目周期都非常长。做产品如果不懂得快速迭代是非常危险的,最小可用集就是只要达到最低可用的限度,就立马拿出去见人,当然范围可以是有限的。根据 真正 用户的反馈,快速调整。这个说起来简单,技术人员做起来很容易失控,我做这款软件,就是花了大量的时间精力去研究技术方面的问题,以至于在某些方面挖的非常深,但是这个东西和我的 大目标 其实没有必然关系,不管技术好不好,差一点就差一点,先做出东西来,先用起来,功能先实现,业务先转起来,论证了这东西基本的可行性,再通过迭代去优化。

第五:做东西尽量不要藏着掖着。没意义,藏着掖着无非怕别人剽窃了自己的创意,想法,这个先不论创意想法有多大实际价值,就算你的想法真的很厉害,如果你没有其它门槛,别人看了就会抄去,那你这个东西一定是会出问题的。门槛这么低,怎么就你想到了?别算别人确实一时没想到,你没有其它门槛,被抄了是迟早的事情,藏着掖着没有用。做了东西就要勇敢拿出来和人交流,正面的就吸纳,负面的就多反思自己。

第六:开发这个软件的过程中,我看完了《人月神话》,《代码大全》,《设计模式》,和其它一些不是那么有名的书籍,一半以上 SharpDeveloper 源代码。很多是在地铁,长途车,火车里看的,当时好像没有平板,有一次在火车上抱着笔记本电脑看《设计模式》,被旁边妹子主动搭讪:“你是程序员吧”,想像一下,绿皮车,一堆人…… 上面讲的几本书我推荐有时间就看一看,特别特别是《代码大全》,一定要看。我的体会是如果没有目标,没有目的的看书学习,很难深切领会,很容易泛泛而谈,我当时看这些书大部分原因是被逼的,因为我总是遇到我搞不定的问题,我必须去寻求解决方案,比如设计模式,我当时也是被逼急了,有结构上的问题搞不定,就到处查资料,看书,一边看一边带着目的的去想,这样行不行,那样行不行,这样成长确实比较快。

 

 

 

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/255862.html

(0)
上一篇 2022年5月18日
下一篇 2022年5月18日

相关推荐

发表回复

登录后才能评论