求大神ps用C#设计一个页面(思路)

我想用C#写一个程序,用来修改已经运行的EXE文件中文本框的值,请问谁有这方面的经验或思路?
我想用C#写一个程序,用来修改已经运行的EXE文件中文本框的值,请问谁有这方面的经验或思路?
10-01-04 & 发布
一、打开程序:点击桌面上的 Visual Basic 图标,在弹出的如图一的窗口中选择“创建标准 EXE”按钮。图一确定后的状态如图二图二这就是创建了一个新的“标准 EXE”文件了。二、工作界面简介:默认的 VB 工作界面由标题栏(1)、菜单栏(2)、工具栏(3)、工具箱面板(4)、程序设计区(5)、项目窗口(6)、属性窗口(7)、布局窗口(8)组成,至于它们具体有什么作用,我们将在以后的实例学习中接触,这里就不予以说明。三、编写我的第一个应用程序:<1>、应用程序要产生的效果:创建的应用程序要有什么样的功能?这是开发每一个应用程序必须最先想到的。我们的第一个应用程序非常简单,使用者只需点击程序上的一个按钮,程序界面上就会显现“跟我来学 VB 神童教程”字样。<2>、开发思路:根据应用程序要实现的功能,那么我们至少需要制作一个按钮、一个程序界面,为了让应用程序更规范,我们还需要创建一个用来显示“跟我来学 VB 神童教程”字样的容器。<3>、具体制作过程:1、创建一个新的“标准 EXE”文件,如第一步所做。需要指出的是,这个以 Form1 为标题栏的程序界面就是我们需要的“程序界面”,也是用户首先看到的对象,所以尽可能将其做得美观一点。当然,对应用界面的美化问题我们将在以后探讨。2、根据开发思路,现在我们来制作按钮。双击工具箱面板上的命令按钮(Command Button)图标,如图三:图三然后你会发现程序界面上多了一个命令按钮,如图四:图四用鼠标拖动新建的按钮到适当位置,如图五:图五再创建一个标签按钮,双击如图六的图标:图六完成后程序界面如图七:图七用鼠标拖动标签按钮到合适位置,如图八:图八将鼠标放在标签按钮左右边缘任意一处,当鼠标呈左右键头时横向拖动,把标签按钮拖长,最后的程序界面如图九:图九3、对按钮属性进行设置:开发任何应用程序,在完成界面布局后,应该就每一个元素进行属性设置以达到自己的要求。当然,也可以在元素布局的过程中进行属性设置。 首先点选箭头状的“选择”图标以便进行选择,如图十: 图十选中程序界面上的命令按钮,然后找到属性面板,如图十一: 图十一其中,“名称:Command1”是此按钮的名称,主要用于程序引用,所以不要用中文名字。 此处,可以不修改按钮的名字,但为了程序更规范,我们将其名字改成“CmdShow”,如图十二: 图十二“Caption:Command1”是命令按钮的标题,也就是显示在命令按钮上的字样,我们将其改成“显示”,如图十三: 图十三用上面的方法,我们将标签按钮的名字改为“LblShow”,如图十四: 图十四将标签按钮的标题改成空字符串,也就是没有任何文字,如图十五: 图十五4、输入程序代码:我们前面讲到的元素布局、属性设置只不过是对应用程序操作界面的定制,要让程序实现功能,关键还得输入程序代码。 选中命令按钮 CmdShow ,然后双击它,弹出如图十六的程序代码输入窗口: 图十六在光标闪烁处输入代码:LblShow.Caption = &跟我来学 VB 神童教程&(这句程序是什么意思?以后我们讲述)。如图十七: 图十七输入完毕,点击右上角的 “X” 回到对象窗口,然后点击工具栏上的“启动”按钮(快捷键:F5),可以看最终结果了!四、知识点:1、我们的第一个程序确实非常简单,但它道出了程序设计的基本方法:首先,应用程序要用来做什么?也就是开发应用程序的目的;其次,应用程序大体上由哪些元素组成?也就是应用程序的操作界面如何,如果可能,最好先用笔把程序界面画出来;然后是对程序界面中每一个元素的属性进行设置;最后输入程序代码和调试。2、前面我们所谈到的“命令按钮”、“标签按钮”,其实它们准确的说法是“命令按钮控件”、“标签按钮控件”,无论是这些控件,还是刚才作为应用程序界面的“窗体”,都是“对象”,因此, VB 是一门面向对象的编程语言,每一个对象都具有很多属性,如大小、位置、标题等等。属性的设置通过属性窗口完成。3、这一点的内容不需强记,在以后的控件讲述中将会涉及。除了“命令控钮控件”、“标签按钮控件”,默认的工具箱面板上还有“指针”工具(用来选择程序设计窗口中的对象)、图片控件(在界面上添加图片)、文本框控件(在界面上显示文本或用来输入文本)、选项框控件(主要用来作为区域划分的控件,一般把相同类型的控件放置在一个选项框中,把其他类型的控件放在其他选项框中)、复选控件(用来制作复选按钮)、单选控件(制作单选按钮)、组合框控件(用来制作功能更为强大的列表框,既有文本框控件的功能,还有列表框控件的功能)、列表框控件(制作各种列表)、滚动条控件(共有横向与竖直两种)、时钟控件(一般用来添加时间触发)、文件操作控件(共有磁盘列表框控件、文件夹列表框、文件列表框三种),另外,还有绘图控件、图像框控件、日期控件。4、VB 提供了丰富的控件选择,除了默认的工具箱面板上的控件外,还有很多控件没有罗列出来,我们可以通过“工程‖部件”命令或在工具箱面板上单击鼠标右键,在弹出的快捷菜单中选择“部件”命令,弹出如图十八的窗口:图十八本窗口罗列了当前系统中所有的控件,只需选中所需控件前面对应的复选框就行了。5、编写程序应该养成好习惯,在给每一个对象命名时首先要保证规范,其次要能“望文生义”,也就是看见一个对象的名字就能知道它是做什么的,如前面我们给命令按钮控件起名为“CmdShow”,一看就知道是用来 Show 的 Command 类型控件。 6、我们最初进入的程序设计界面是对象界面,进入代码界面的办法很简单,前面用到的双击控件是一种办法,另外还可以通过点击项目窗口中的“查看代码”按钮进入,如果点按旁边的“查看对象”按钮就会又回到原来的对象界面。如图十九: 图十九7、在前面的例子:LblShow.Caption = &跟我来学 VB 神童教程&中,“=”并不是数学中的等号,而是一种赋值符号,表示:将“跟我来学 VB 神童教程”这个字符串赋值给 LblShow ,并作为它的标题。 另外如:X = X+6 ,在数学中,这种表达式不存立,而在 VB 中,是指在 X 本来的基础上加 6 ,然后把结果重新赋给 X ,这时 X 的值不再是原来的数字,而是加上 6 后的值。 8、程序的保存:在 VB 中进行保存,常常用“保存工程”命令,而在保存过程中,必须保存两次,一次是以 .frm 为扩展名的文件保存,另一次是以 .VBP 为扩展名的文件保存。前者是保存应用程序的窗体文件,后者是保存应用程序的工程文件。如图二十与图二十一: 图二十
请登录后再发表评论!
一、打开程序:点击桌面上的 Visual Basic 图标,在弹出的如图一的窗口中选择“创建标准 EXE”按钮。图一确定后的状态如图二图二这就是创建了一个新的“标准 EXE”文件了。二、工作界面简介:默认的 VB 工作界面由标题栏(1)、菜单栏(2)、工具栏(3)、工具箱面板(4)、程序设计区(5)、项目窗口(6)、属性窗口(7)、布局窗口(8)组成,至于它们具体有什么作用,我们将在以后的实例学习中接触,这里就不予以说明。三、编写我的第一个应用程序:<1>、应用程序要产生的效果:创建的应用程序要有什么样的功能?这是开发每一个应用程序必须最先想到的。我们的第一个应用程序非常简单,使用者只需点击程序上的一个按钮,程序界面上就会显现“跟我来学 VB 神童教程”字样。<2>、开发思路:根据应用程序要实现的功能,那么我们至少需要制作一个按钮、一个程序界面,为了让应用程序更规范,我们还需要创建一个用来显示“跟我来学 VB 神童教程”字样的容器。<3>、具体制作过程:1、创建一个新的“标准 EXE”文件,如第一步所做。需要指出的是,这个以 Form1 为标题栏的程序界面就是我们需要的“程序界面”,也是用户首先看到的对象,所以尽可能将其做得美观一点。当然,对应用界面的美化问题我们将在以后探讨。2、根据开发思路,现在我们来制作按钮。双击工具箱面板上的命令按钮(Command Button)图标,如图三:图三然后你会发现程序界面上多了一个命令按钮,如图四:图四用鼠标拖动新建的按钮到适当位置,如图五:图五再创建一个标签按钮,双击如图六的图标:图六完成后程序界面如图七:图七用鼠标拖动标签按钮到合适位置,如图八:图八将鼠标放在标签按钮左右边缘任意一处,当鼠标呈左右键头时横向拖动,把标签按钮拖长,最后的程序界面如图九:图九3、对按钮属性进行设置:开发任何应用程序,在完成界面布局后,应该就每一个元素进行属性设置以达到自己的要求。当然,也可以在元素布局的过程中进行属性设置。 首先点选箭头状的“选择”图标以便进行选择,如图十: 图十选中程序界面上的命令按钮,然后找到属性面板,如图十一: 图十一其中,“名称:Command1”是此按钮的名称,主要用于程序引用,所以不要用中文名字。 此处,可以不修改按钮的名字,但为了程序更规范,我们将其名字改成“CmdShow”,如图十二: 图十二“Caption:Command1”是命令按钮的标题,也就是显示在命令按钮上的字样,我们将其改成“显示”,如图十三: 图十三用上面的方法,我们将标签按钮的名字改为“LblShow”,如图十四: 图十四将标签按钮的标题改成空字符串,也就是没有任何文字,如图十五: 图十五4、输入程序代码:我们前面讲到的元素布局、属性设置只不过是对应用程序操作界面的定制,要让程序实现功能,关键还得输入程序代码。 选中命令按钮 CmdShow ,然后双击它,弹出如图十六的程序代码输入窗口: 图十六在光标闪烁处输入代码:LblShow.Caption = &跟我来学 VB 神童教程&(这句程序是什么意思?以后我们讲述)。如图十七: 图十七输入完毕,点击右上角的 “X” 回到对象窗口,然后点击工具栏上的“启动”按钮(快捷键:F5),可以看最终结果了!四、知识点:1、我们的第一个程序确实非常简单,但它道出了程序设计的基本方法:首先,应用程序要用来做什么?也就是开发应用程序的目的;其次,应用程序大体上由哪些元素组成?也就是应用程序的操作界面如何,如果可能,最好先用笔把程序界面画出来;然后是对程序界面中每一个元素的属性进行设置;最后输入程序代码和调试。2、前面我们所谈到的“命令按钮”、“标签按钮”,其实它们准确的说法是“命令按钮控件”、“标签按钮控件”,无论是这些控件,还是刚才作为应用程序界面的“窗体”,都是“对象”,因此, VB 是一门面向对象的编程语言,每一个对象都具有很多属性,如大小、位置、标题等等。属性的设置通过属性窗口完成。3、这一点的内容不需强记,在以后的控件讲述中将会涉及。除了“命令控钮控件”、“标签按钮控件”,默认的工具箱面板上还有“指针”工具(用来选择程序设计窗口中的对象)、图片控件(在界面上添加图片)、文本框控件(在界面上显示文本或用来输入文本)、选项框控件(主要用来作为区域划分的控件,一般把相同类型的控件放置在一个选项框中,把其他类型的控件放在其他选项框中)、复选控件(用来制作复选按钮)、单选控件(制作单选按钮)、组合框控件(用来制作功能更为强大的列表框,既有文本框控件的功能,还有列表框控件的功能)、列表框控件(制作各种列表)、滚动条控件(共有横向与竖直两种)、时钟控件(一般用来添加时间触发)、文件操作控件(共有磁盘列表框控件、文件夹列表框、文件列表框三种),另外,还有绘图控件、图像框控件、日期控件。4、VB 提供了丰富的控件选择,除了默认的工具箱面板上的控件外,还有很多控件没有罗列出来,我们可以通过“工程‖部件”命令或在工具箱面板上单击鼠标右键,在弹出的快捷菜单中选择“部件”命令,弹出如图十八的窗口:图十八本窗口罗列了当前系统中所有的控件,只需选中所需控件前面对应的复选框就行了。5、编写程序应该养成好习惯,在给每一个对象命名时首先要保证规范,其次要能“望文生义”,也就是看见一个对象的名字就能知道它是做什么的,如前面我们给命令按钮控件起名为“CmdShow”,一看就知道是用来 Show 的 Command 类型控件。 6、我们最初进入的程序设计界面是对象界面,进入代码界面的办法很简单,前面用到的双击控件是一种办法,另外还可以通过点击项目窗口中的“查看代码”按钮进入,如果点按旁边的“查看对象”按钮就会又回到原来的对象界面。如图十九: 图十九7、在前面的例子:LblShow.Caption = &跟我来学 VB 神童教程&中,“=”并不是数学中的等号,而是一种赋值符号,表示:将“跟我来学 VB 神童教程”这个字符串赋值给 LblShow ,并作为它的标题。 另外如:X = X+6 ,在数学中,这种表达式不存立,而在 VB 中,是指在 X 本来的基础上加 6 ,然后把结果重新赋给 X ,这时 X 的值不再是原来的数字,而是加上 6 后的值。 8、程序的保存:在 VB 中进行保存,常常用“保存工程”命令,而在保存过程中,必须保存两次,一次是以 .frm 为扩展名的文件保存,另一次是以 .VBP 为扩展名的文件保存。前者是保存应用程序的窗体文件,后者是保存应用程序的工程文件。如图二十与图二十一: 图二十
请登录后再发表评论!
要用到线程插入技术需要调用windows底层的api
请登录后再发表评论! 上传我的文档
 下载
 收藏
该文档贡献者很忙,什么也没留下。
 下载此文档
正在努力加载中...
C#程序设计用C#实现一个简单的贪吃蛇游戏
下载积分:1000
内容提示:C#程序设计用C#实现一个简单的贪吃蛇游戏
文档格式:DOC|
浏览次数:211|
上传日期: 23:22:04|
文档星级:
该用户还上传了这些文档
C#程序设计用C#实现一个简单的贪吃蛇游戏.DOC
官方公共微信C#程序设计用C#实现一个简单的贪吃蛇游戏贪吃蛇,贪吃蛇游戏,贪吃蛇代码
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
C#程序设计用C#实现一个简单的贪吃蛇游戏
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口用C#写的一个简单万年历
还有哪里可以优化
希望高手指出来 希望有思路更清晰的
[问题点数:40分,结帖人saying_ayo]
用C#写的一个简单万年历
还有哪里可以优化
希望高手指出来 希望有思路更清晰的
[问题点数:40分,结帖人saying_ayo]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
相关帖子推荐:
2015年2月 .NET技术大版内专家分月排行榜第二2015年1月 .NET技术大版内专家分月排行榜第二2014年11月 .NET技术大版内专家分月排行榜第二2014年5月 .NET技术大版内专家分月排行榜第二2014年4月 .NET技术大版内专家分月排行榜第二2012年2月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第二
2015年5月 .NET技术大版内专家分月排行榜第三2015年4月 .NET技术大版内专家分月排行榜第三2014年12月 .NET技术大版内专家分月排行榜第三2014年10月 .NET技术大版内专家分月排行榜第三2014年9月 .NET技术大版内专家分月排行榜第三2014年1月 .NET技术大版内专家分月排行榜第三2013年12月 .NET技术大版内专家分月排行榜第三2013年10月 .NET技术大版内专家分月排行榜第三2013年5月 .NET技术大版内专家分月排行榜第三2011年9月 .NET技术大版内专家分月排行榜第三2011年2月 .NET技术大版内专家分月排行榜第三2010年2月 .NET技术大版内专家分月排行榜第三
2015年2月 .NET技术大版内专家分月排行榜第二2015年1月 .NET技术大版内专家分月排行榜第二2014年11月 .NET技术大版内专家分月排行榜第二2014年5月 .NET技术大版内专家分月排行榜第二2014年4月 .NET技术大版内专家分月排行榜第二2012年2月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第二
2015年5月 .NET技术大版内专家分月排行榜第三2015年4月 .NET技术大版内专家分月排行榜第三2014年12月 .NET技术大版内专家分月排行榜第三2014年10月 .NET技术大版内专家分月排行榜第三2014年9月 .NET技术大版内专家分月排行榜第三2014年1月 .NET技术大版内专家分月排行榜第三2013年12月 .NET技术大版内专家分月排行榜第三2013年10月 .NET技术大版内专家分月排行榜第三2013年5月 .NET技术大版内专家分月排行榜第三2011年9月 .NET技术大版内专家分月排行榜第三2011年2月 .NET技术大版内专家分月排行榜第三2010年2月 .NET技术大版内专家分月排行榜第三
2014年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第四
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。西西软件下载最安全的下载网站、值得信赖的软件下载站!
您的位置:
→ 关于用C#实现B/S与C/S平台之间功能通用性的设计思路
1. 有A,B两组开发人员进行某个系统的开发,其中A组开发人员负责B/S平台的功能设计与开发,B组开发人员负责C/S平台的功能设计与开发。
2. 在当时的项目背景下,B/S端的项目是先启动的,而A组的开发人员还没有意识到将来需要配合C/S端来做功能协作,因此产生的问题就是,前期的系统架构设计没有过多地考虑以适应多个平台下的功能适应性。当然,从B/S端的设计角度上看,系统架构还算比较清晰。接着A组的开发人员就在这样的情况下,完成了系统功能的实现。
3. 接着高层领导告诉项目经理需要做一套C/S架构的软件来配合B/S端平台的使用,而这时候B/S端的功能实现已经基本完成,B组开发人员成立。
4. 在B组架构人员开始设计架构的时候,并没有衍用B/S端的开发架构,很多基础架构(如分层模式、结构、数据实体类等等)都存在很大的差异(C/S端项目在初期的要求没有那么高,有的功能能削减掉就削减掉),后来B组架构人员发现需求文档上的有个功能和B/S平台上的某个功能是一样的,于是他和A组架构人员进行交流,希望负责B/S平台上这个功能的开发人员能够帮助C/S平台帮助完成这一功能。于是A组的Leepy就匆匆忙忙地上阵了。
5. 最初Leepy同学因为在B/S平台上也有大量的任务需要完成,任务赶得狠,又收到这样一个&功能复制&的任务,心想:&那么就先把功能复制一份上去,然后如果B/S平台上的功能有更新,就同步修改C/S平台就好&。于是打开C/S平台的项目,发现和B/S平台项目的差异性比较大,包括数据库结构和数据实体类等等,更头疼的是这里采用的是. 2.0进行开发,而B/S端采用的是 3.5进行开发,而且从功能上,Leepy使用大量的3.5的属性。要直接复用是不可能的,还需要调整相应的代码。
6. 于是C/S平台该功能出来了,运行得还行。现在才是郁闷的开始,因为该功能属于平台的核心模块,于是B/S平台上要时刻调整得比较大,所以同步的C/S端的功能也要相应的调整,然后又运行完好。于是问题出来了,这样反复地修改导致系统(C/S和B/S)维护成本很高,架构间的设计耦合度太大。刚开始Leepy抱怨为什么C/S端没有和B/S端统一架构,至少底层基础平台能够设计得具有可扩展性,光光抱怨无法解决问题,因为这是项目的人员配置的问题。于是,Leepy想到了必须对该功能进重构,使用一个通用的组件进行抽象,而实际实现的,如C/S、B/S端具体应用,只要维护相应的业务代码。
1. 说完场景,现在说说动手的部分。以一个中学生教育平台591up的网站为例,以及教育平台客户端的辅助软件。
这一功能实现一份Word文档试卷的导入保存并分解文档中的试题,将试题逐个保存入库(解析出来的试题部分还包括很多属性,如答案、知识点、解题关键点等很多属性)。现在B/S平台和C/S平台都需要这个功能,但是B/S平台和C/S平台下的相关数据库实体类,设计不很统一,导致维护系统的成本很高。于是,考虑是否能将解析器的设计与业务功能分开,将试卷解析器设计成通用的组件,而与B/S端和C/S端的业务代码彻底分开,对于解析的逻辑代码(基础代码)在两端都可以引用到,而B/S端和C/S端所需要做得就是调整业务代码,并不需要关解析的基础代码是什么,组件与业务代码解耦。如下图所示:
2. 现在讲讲具体设计思路,先从试卷解析器基础组件开始(为了简化,该范例是削弱版的),创建一个.net 2.0的类库(为了适应客户端.net 2.0的配置)声明一个试卷解析器范型接口:
/// &summary&
/// 试卷转换器泛型接口
/// &/summary&
public interface IPaperConvertor&TIn, TOut&
/// &summary&
/// 转换方法
/// &/summary&
/// &param name=&tIn&&转换输入类型&/param&
/// &param name=&helper&&Word处理接口&/param&
/// &returns&转换输出类型&/returns&
TOut Convert(TIn tIn, IWordHelper helper);
其中TIn类型作为输入类型,TOut类型作为输出类型(TIn将来作为业务代码中实际的输入类型,如WordInfo类;TOut作为实际输出类型,如PaperInfo类;IWordHelper为一个Word处理接口,这里的实现是Microsoft.Office.Interop.Word)
考虑到转换器在转换过程Convert中,会产生一系列的步骤,首先对于转换这个过程进行细化,分解成各个步骤:
public abstract class BasePaperConvertor&TIn, TOut& : IPaperConvertor&TIn, TOut&
where TIn : class, new()
where TOut : class, new()
/// &summary&
/// 输出试卷实体
/// &/summary&
protected TOut Paper { }
/// &summary&
/// 输入Word条件
/// &/summary&
protected TIn WordInfo { }
#region Word操作实体属性
/// &summary&
/// Word操作实体属性
/// &/summary&
protected IWordHelper WordHelper { }
#endregion
//公共方法
/// &summary&
/// 转换方法
/// &/summary&
/// &param name=&tIn&&&/param&
/// &returns&&/returns&
public virtual TOut Convert(TIn tIn, IWordHelper helper)
WordHelper =
WordInfo = tIn;
Paper = Initialize(tIn);
if (Prepare())
Execute();
Finished();
//抽象方法
/// &summary&
/// 初始化
/// &/summary&
/// &param name=&tIn&&&/param&
/// &returns&&/returns&
protected abstract TOut Initialize(TIn tIn);
/// &summary&
/// 预装载
/// &/summary&
/// &param name=&tOut&&&/param&
/// &returns&&/returns&
protected abstract bool Prepare();
/// &summary&
/// &/summary&
/// &param name=&tOut&&&/param&
protected abstract void Execute();
/// &summary&
/// &/summary&
protected abstract void Finished();
从代码中,我们可以看到Convert方法中调用了一系列的抽象方法,首先对于输入类型进行初始化(Initialize),接着通过输入类型预装载(Prepare),如果预装载成功,并开始执行。最后完成(Finished)所有的工作。
接着,需要定义一个包含Word解析逻辑代码的抽象类,这里使用Microsoft.Office.Interop.Word进行Office编程,于是创建名为
OfficeWordPaperConvertor.cs的类:
OfficeWordPaperConvertor
/// &summary&
/// 试卷解析器泛型抽象类
/// &/summary&
public abstract class OfficeWordPaperConvertor&TIn, TQuestion, TOut& : BasePaperConvertor&TIn, TOut&
where TIn : class, new()
where TQuestion : class, new()
where TOut : class, new()
#region 试卷Word结构信息
/// &summary&
/// 试卷Word结构信息
/// &/summary&
protected PaperWordInfo PaperWordInfo { }
#endregion
#region Word操作辅助类属性
private OfficeWordHelper _OfficeWordH
/// &summary&
/// Word操作辅助类属性
/// &/summary&
protected OfficeWordHelper OfficeWordHelper
if (_OfficeWordHelper == null)
_OfficeWordHelper = GetWordHelper();
return _OfficeWordH
#endregion
#region 预处理试卷
/// &summary&
/// 预处理试卷
/// &/summary&
/// &param name=&tOut&&&/param&
/// &returns&&/returns&
protected override bool Prepare()
//过滤试卷无效信息
FilterPaper();
//解析试卷
ParsePaper();
#endregion
#region 执行试卷
/// &summary&
/// 执行试卷
/// &/summary&
/// &param name=&tOut&&&/param&
protected override void Execute()
for (int i = 0; i & PaperWordInfo.C i++)
QuestionWordInfo questionWordInfo = PaperWordInfo[i];
//执行试题
ExcuteQuestion(questionWordInfo);
#endregion
#region 完成时调用
/// &summary&
/// 完成时调用
/// &/summary&
protected override void Finished()
//这里进行完成时调用的实现
#endregion
/// &summary&
/// 过滤试卷无效信息
/// &/summary&
protected virtual void FilterPaper()
/// &summary&
/// 解析试卷
/// &/summary&
protected virtual void ParsePaper()
PaperWordInfo = new PaperWordInfo();
//通过计算 OfficeWordHelper.Document.Text 得到文本中的题目数,这里省去这段逻辑
PaperWordInfo.AddQuestion(new QuestionWordInfo { StartIndex = 0, EndIndex = 0 });
PaperWordInfo.AddQuestion(new QuestionWordInfo { StartIndex = 1, EndIndex = 1 });
PaperWordInfo.AddQuestion(new QuestionWordInfo { StartIndex = 2, EndIndex = 2 });
/// &summary&
/// 执行试题
/// &/summary&
/// &param name=&questionWordInfo&&&/param&
protected virtual void ExcuteQuestion(QuestionWordInfo questionWordInfo)
string[] array = OfficeWordHelper.Document.Text.Split(new string[] { &\r\n& }, StringSplitOptions.RemoveEmptyEntries);
//创建试题解析器实体
TQuestion question = CreateQuestionConvertor(WordInfo, array[questionWordInfo.StartIndex]);
//将试题添加到试卷中
if (question != null) AddQuestion(question);
#region 获取Word工具类
/// &summary&
/// 获取Word工具类
/// &/summary&
/// &returns&&/returns&
protected OfficeWordHelper GetWordHelper()
return WordHelper as OfficeWordH
#endregion
//抽象方法
/// &summary&
/// 创建试题解析器实体
/// &/summary&
/// &param name=&subject&&&/param&
protected abstract TQuestion CreateQuestionConvertor(TIn tIn, string wordContent);
/// &summary&
/// 将试题添加到试卷中
/// &/summary&
/// &param name=&tPart&&&/param&
/// &param name=&tQuestion&&&/param&
protected abstract void AddQuestion(TQuestion tQuestion);
为何这里没有重写Initialize方法呢?由于这里需要将Initialize暴露于业务代码中,可以通过业务代码来重写该方法,如果业务组件没有调用Initialize,将报错。
这里Prepare方法主要完成一份Word文档的信息过滤,并且将文档中按照试题题号进行拆分试题,形成试题列表。
Execute方法完成一份试卷的执行,通过试题列表将题目逐题入库。
Finshed方法在Execute之后,可通过事件委托告诉用户解析已经完成。
在后面附加的例子中,我会引用OfficeWordHelper.Document.Text 等于&1.试题1\r\n2.试题2\r\n3.试题3&的文本字符串来模拟Word文档中的文字(实际情况更
加复杂,Word文档中包括图片,符号,OLE对象等等,一切为了简化说明,这里省略该步骤),说明它拆分出来的试题有3道。QuestionWordInfo 类的
StartIndex,EndIndex对应试题所在行数索引。
接着注意ExcuteQuestion这个方法,调用了CreateQuestionConvertor和AddQuestion两个抽象方法。该两个抽象方法将在业务组件中实现。
试卷解析器基本设计实现了,现在看下试题解析器该如何实现:
声明一个试题解析器范型接口:
/// &summary&
/// 试题转换器泛型接口
/// &/summary&
public interface IQuestionConvertor&TIn, TOut&
TOut Convert(TIn tIn, string wordContent);
其中TIn类型作为输入类型,TOut类型作为输出类型(TIn将来作为业务代码中实际的输入类型,如WordInfo类;TOut作为实际输出类型,如QuestionInfo类)
考虑到转换器在转换过程Convert中,会产生一系列的步骤,首先对于转换这个过程进行细化,分解成各个步骤:
public abstract class BaseQuestionConvertor&TIn, TOut& : IQuestionConvertor&TIn, TOut& where TIn : class, new()
#region 输出试卷属性
/// &summary&
/// 输出试卷实体
/// &/summary&
protected TOut Question { }
#endregion
#region 输入Word实体属性
/// &summary&
/// 输入Word实体属性
/// &/summary&
protected TIn WordInfo { }
#endregion
//公共方法
#region 转换方法
/// &summary&
/// 转换方法
/// &/summary&
/// &param name=&tIn&&&/param&
/// &param name=&helper&&&/param&
/// &returns&&/returns&
public virtual TOut Convert(TIn tIn, string wordContent)
WordInfo = tIn;
Question = Initialize(tIn);
//解析试题
TOut tOut = Execute(wordContent);
Finished();
#endregion
//抽象方法
#region 初始化
/// &summary&
/// 初始化
/// &/summary&
/// &param name=&tIn&&&/param&
/// &returns&&/returns&
protected abstract TOut Initialize(TIn tIn);
#endregion
#region 执行
/// &summary&
/// &/summary&
/// &param name=&tOut&&&/param&
protected abstract TOut Execute(string wordContent);
#endregion
#region 完成
/// &summary&
/// &/summary&
protected abstract void Finished();
#endregion
接着,需要定义一个包含Word解析逻辑代码的抽象类,这里使用Microsoft.Office.Interop.Word进行Office编程,于是创建名为
OfficeWordQuestionConvertor.cs的类:
OfficeWordQuestionConvertor /// &summary&
/// 试题解析器泛型抽象类
/// &/summary&
public abstract class OfficeWordQuestionConvertor&TIn, TOut& : BaseQuestionConvertor&TIn, TOut&
where TIn : class, new()
where TOut : class, new()
protected override TOut Execute(string wordContent)
ParseQuestionContent(wordContent);
ParseDifficultyCode(wordContent);
//...其他解析属性,这里省略
#region 解析试题题干
/// &summary&
/// 解析试题题干
/// &/summary&
/// &returns&&/returns&
protected virtual void ParseQuestionContent(string questionText)
//通过questionText解析出试题提干,这里省略
string content = questionT
SetQuestionContent(content);
#endregion
#region 解析试题难度
/// &summary&
/// 解析试题难度
/// &/summary&
/// &param name=&questionText&&&/param&
/// &returns&&/returns&
protected virtual void ParseDifficultyCode(string questionText)
//通过questionText解析出难度文本,这里省略
string difficulty = &A&;
SetDifficultyCode(difficulty);
#endregion
//抽象方法
/// &summary&
/// 设置试题标题
/// &/summary&
/// &param name=&text&&&/param&
protected abstract void SetQuestionContent(string text);
/// &summary&
/// 设置试题难度
/// &/summary&
/// &param name=&difficulty&&&/param&
protected abstract void SetDifficultyCode(string difficulty);
Execute方法通过Word文本内容解析相应试题的属性(如题干、难度、是否系统试题等)。
于是这里抽象出了两个方法(按照需求来进行方法扩展),SetQuestionContent和SetDifficultyCode将在业务组件中实现。
3. 现在开始创建其他项目,如下图所示:
其中WebApp为B/S平台项目,WebApp.Lib为B/S平台业务类库,两个项目均采用.net framework 3.5;WinApp为C/S平台项目,WinApp.Lib为C/S业务类库;
注意到,WebApp.Lib和WinApp.Lib在数据实体类上存在差异(实际情况差异更大,不仅仅数据实体类上,这里为了简化),两个项目均采用.net framework 2.0;
WordConvertor即为上面说的解析器组件。
以WebApp.Lib为例,实现业务试卷和试题解析器:
WebPaperConvertor .cs:
/// &summary&
/// Web端试卷解析器
/// &/summary&
public class WebPaperConvertor : OfficeWordPaperConvertor&WordInfo, QuestionInfo, PaperInfo&
/// &summary&
/// 初始化试卷
/// &/summary&
protected override PaperInfo Initialize(WordInfo wordInfo)
Paper = new PaperInfo();
Paper.Title = wordInfo.PaperT
/// &summary&
/// 创建试题解析器
/// &/summary&
protected override QuestionInfo CreateQuestionConvertor(WordInfo wordInfo, string wordContent)
WebQuestionConvertor convertor = new WebQuestionConvertor();
return convertor.Convert(wordInfo, wordContent);
/// &summary&
/// 增加试题
/// &/summary&
protected override void AddQuestion(QuestionInfo tQuestion)
if(Paper.QuestionInfoList == null)
Paper.QuestionInfoList = new List&QuestionInfo&();
Paper.QuestionInfoList.Add(tQuestion);
//其他业务扩展...
WebQuestionConvertor .cs:
/// &summary&
/// Web端试题解析器
/// &/summary&
public class WebQuestionConvertor : OfficeWordQuestionConvertor&WordInfo, QuestionInfo&
/// &summary&
/// 根据条件初始化试题
/// &/summary&
protected override QuestionInfo Initialize(WordInfo wordInfo)
QuestionInfo questionInfo = new QuestionInfo();
questionInfo.IsSystem = wordInfo.IsS
return questionI
/// &summary&
/// 完成解析后触发
/// &/summary&
protected override void Finished()
/// &summary&
/// 设置试题题干
/// &/summary&
protected override void SetQuestionContent(string text)
Question.QuestionContent =
/// &summary&
/// 设置试题难度
/// &/summary&
protected override void SetDifficultyCode(string difficulty)
switch (difficulty)
Question.DifficultyCode = 1;
Question.DifficultyCode = 2;
Question.DifficultyCode = 3;
//其他业务扩展...
从类中可以看出,它们分别继承于OfficeWordPaperConvertor和OfficeWordQuestionConvertor类,这里实现的只是和平台相关的业务逻辑,至于如何对一份Word文档解析,交给解析器组件去做,平台上无需知道。
同理,C/S平台也用了类似的方法,不同的只是个别类型通过泛型抽象类得到实现。并且能够使B/S平台和C/S平台拥有各自的业务逻辑。
这样,维护两个平台的这个功能成本降低了,如果解析器组件需要改动,只要更动基础组件的设计,而不会影响业务上的逻辑。
这是Leepy同学在开发项目的时候遇到的问题,可以说是提供了一种思路吧,也可以算是经验之谈吧:)
在591up以及客户端的功能效果如下图所示:
591up 客户端软件
最后附上该范例的
阅读本文后您有什么感想? 已有
人给出评价!
访问量多的

我要回帖

更多关于 大神求放过 的文章

 

随机推荐