C#案例教学之模拟资源管理器浏览功能
2013-04-07段莎莉
□段莎莉
( 山西国际商务职业学院 信息系,山西 太原 030031)
一、案例设计背景
高等职业教育具有“高等教育”和“职业教育”的双重属性,是高等教育发展中的一个类型,不是其中一个层次,具有不可替代的作用,其培养的目标定位明确为培养一线的劳动者、操作者、服务者和管理者。有了职业技能,就能获得企业运作的基层经验,再加上高职院校不同于职业培训机构的综合素质的培养,才能进一步提升就业空间,实现人才的可持续发展。计算机与应用技术作为高职教育设置的传统专业,我们秉承“工学结合,以能力为本位、以职业实践为主线”的高职教育理念制定人才培养方案,设置课程体系,开设课程时充分考虑学生的就业,适当选取时下热门实用的语言。基于这种考虑,将《C#程序设计》作为专业核心课程,C#是微软公司专门为.net平台设计的完全面向对象的语言,从C,C++和Java等多种语言继承发展而来,博采众长,简言之,综合了图形化可视操作和C++的高运行效率,以其强大的操作能力、优雅的语法风格、创新的语言特性和便捷的面向组件编程的支持成为.net开发平台的首选语言,是学生就业时必备杀手锏之一。该课程紧跟企业技术应用和人才需求岗位而开设,教学中以项目开发过程为导向,采用案例教学法,目的是培养学生具备应用管理软件底层代码的能力,职业定位是企业Visual C#.net程序员,注重核心职业技能和职业素质的培养。
我国自上世纪引入案例教学法,在各个学科深入开展广泛应用,取得了较好的教学效果。它是在教师的指导下,根据教学目的要求,组织学生对案例的调查、阅读、思考、分析、讨论和交流等活动,教给他们分析问题和解决问题的方法或道理,进而提高分析问题和解决问题的能力,加深学生对基本原理和概念的理解的一种特定的教学方法。这个过程中案例的选取是关键,案例内容应具有一定的代表性和普遍性,涉及的知识多且全面,通过学习能让学生举一反三,从多角度对所学理论加以验证,从中得出正确结论。有了这样的思路,我们加大了《C#程序设计》课程案例选取的深度和广度,向步入准职业领域方向过渡,扩大案例所涉及知识范围,加长读写代码篇幅,通过合适的项目引导,激发学习兴趣,进而把理论教学与实践教学有机地结合起来,充分发掘学生的创造潜能。
二、windows资源管理器仿真模拟案例的实现
(一)界面设计
界面为带有标题栏、菜单栏、工具栏、地址栏、状态栏和用splitCotainer容器分割控件分成左右两部分的TreeView树形结构控件和ListView列表视图控件,左边用splitContainer分成上下两部分,上面放置“文件夹”工具条用于转换“资源管理器”视图,下面放置TreeView树形结构控件,为了让程序适应窗体大小的改变,设置splitCotainer和内置控件停靠属性dock为fill,且分割控件的固定面板设置为panel1,当窗体调整大小时panel1能保持不变。另外,读者可能头疼按钮图标,可以采用系统默认的图标。
在设计阶段纵然让地址栏上的各个按钮布满工具栏的宽度,由于放置地址组合框的工具栏的dock属性为top,所以随着窗体大小改变,工具栏的宽度是会随着放宽,并且“地址”标签和“转到”按钮是左、右对齐,造成在地址组合框和“转到”按钮之间留下了间隙,故在工具栏的Resize事件中重新计算并调整地址组合框的宽度,通过foreach循环将除地址组合框以外的项目的宽度相加,用工具栏的新宽度将其减去再减一定的数值,为的是调整完宽度不让其它项目溢出。
(二)功能实现
仿真设计的功能实现完全参考windows资源管理器的浏览功能设计。
1.加载本地磁盘列表。窗体加载时调用ListDrivers()加载本地磁盘列表,首先将treeview中的结点清空,再用treeview的add(“结点名称”)方法动态添加名为“我的电脑”根结点nodes[0]并使其成为selectednode,由于窗体加载和选择根结点时都要加载本地磁盘列表,清空结点避免本地磁盘列表重复添加,动态添加避免清空在设计阶段添加的根结点后找不到nodes[0],无法将本地磁盘列表作为“我的电脑”的子结点添加进去。
有了根结点后通过代码将本地磁盘列表作为其子结点动态地加入treeview中,使用DriveInfo类的GetDrives()方法提取本地逻辑磁盘盘符(如C:等)到字符串数组中,采取循环方法将数组元素生成treenode添加到treeview1.nodes[0],同时生成listviewitem添加到listview中,一是为了正确显示结点名称,通过判断drivetype来区别“本地磁盘、CDROM和可移动磁盘”,并修改结点的text属性;二是为了正确显示结点图标,将treeview调整为小图标视图并与imagelist1相关联,listview调整为大图标视图与imagelist2相关联。
2.加载逻辑磁盘资源。该功能在treeView_BeforeExpand事件中实现,结点即将展开前触发事件,通过事件参数e定位到每个即将展开的结点,也就是即将被单击“+”号的结点,只要分配给当前结点的集合不为空,通过调用NodeUpdate(e.node)[1]就能将各级结点的子目录作为子结点添加到其集合中。首先调用自定义GetFilePath(e.node)[2]获取当前结点绝对路径,用它生成操作文件夹的目录对象,用GetDirectories()方法提取该对象的子目录集合,由于每个结点子目录集合的元素个数不定,故循环的次数不定,只能采用foreach循环将集合中的对象生成treenode作为当前结点e的子结点添加到treeview中,由于treeview控件和imagelist1相关联,所以将新加下结点的图标设置为imaglist1中索引为4的文件夹图标,将其选择后的图标设置为索引为5即呈打开状态的文件夹图标。首次加入时显示为文件夹关闭图标,当单击成为所选对象后显示为文件夹打开图标。
GetFilePath(TreeNode node) 方法和系统提供的node.fullpath属性实现的功能一样,但是由于在加载磁盘列表时修改了其text属性,fullpath属性得不到结点的绝对路径,故改写其实现过程为GetFilePath(),通过判断所选结点的text属性,如果选择根结点“我的电脑”,则返回空字符路径,表示没有合法路径;如果选择“本地磁盘”结点,则返回node.name即drive.name,这就解决了name和text不一致的问题;如果选择“本地磁盘的子目录”结点,则递归调用GetFilePath(),层层向上直至遍历到“本地磁盘”,从而得到该结点的fullpath。
3.浏览逻辑磁盘资源。该功能分为正向和反向两部分来实现,正向浏览是单击treeview结点在listview中加载相应资源,反向浏览是激活listview中资源结点的同时在treeview中相应结点处于被选择状态。
正向浏览功能在treeView1_ AfterSelect事件中实现,结点被选择后触发事件,通过事件参数e提供数据且能定位到当前被选择的结点,调用ListUpdate(GetFilePath(e.node))[3]就能将当前结点的子目录和子文件添加到listview控件中。首先,将listview清空,因为每选择一个结点就会加载其子目录和子文件,如果不清空listview,就会将新增listitem添加到原来加载的项目之后,出现不合理的逻辑结构。
其次,该方法调用当前结点的路径即GetFilePath(e.node)作参数,在加载listview项目时如果选择“我的电脑”根结点则返回空字符串的无效路径,此时调用ListDrivers()方法用大图标的形式加载本地磁盘列表;否则,先创建当前有效结点e.node文件夹对象DirectoryInfo currentDir = new DirectoryInfo(newPath),获取子目录集合currentDir.GetDirectories()和子文件集合currentDir.GetFiles()分别生成treenode结点和listviewitem项目,用foreach循环将其依次添加到treeview和listview中,并统计其count更新到状态栏中。
第三,添加子文件时关键问题是图标的获取,用GetSystemIcon[4]类GetIconByFileName方法获取后将其添加到与之关联的小图标显示控件Imagelist1集合中以备后用。
需注意的两个问题:(1)由于系统中扩展名为exe的文件图标不尽相同,故添加exe图标时不能用扩展名作关键字,而是用文件名作关键字,且每次添加新的子文件前先将与之关联的Imagelist1中的exe图标清除,防止套用不正确的exe图标;(2)非exe文件的图标用其扩展名作关键字将其图标添加到Imagelist1中,故添加非exe文件时先根据扩展名判断Imagelist1中有无这类文件的图标,有就直接用,没有就先添加后再使用。
反向浏览功能在listView1_ItemActivate事件中实现,双击激活listview中的项目后发生。实现时,首先将TreeView的HideSelection属性设为False,意味着即使TreeView失去焦点,先前所选择的结点依旧将以灰色背景被显示出来,这样可以保留访问TreeView结点的路径痕迹;其次在加载本地磁盘列表时将“我的电脑”根结点列为SelectedNode,这样初始运行程序时相当于单击了我的电脑,也能为后续查找listview中被激活项目时提供父结点;(3)在listView1_ItemActivate事件中添加代码,通过foreach循环在TreeView.SelectedNode的集合中查找与ListView被激活项目Text一致的结点,让其成为新的被选结点。
4.仅展开被选结点。该功能在Treeview1_AfterExpand事件中实现,该事件在treeview控件中的结点展开后触发,用来控制展开当前结点的同时,折叠上次打开的兄弟结点,判断当前结点的PreNode和NextNode同级树结点,如果存在就将其折叠,通过循环,层层深入取得其所有的PreNode和NextNode,将其折叠,直到其不存在为止。
三、教学效果评价
案例教学法的优势在于:
第一,引导学生将所学课本知识转化为解决问题的实际应用能力;大多数计算机专业的毕业生在回答能干什么时,往往列举一堆课程名称却举不出自己已完成的有代表性的案例项目,而案例教学法的实施过程中,学生拿到案例后,先进行消化,再主动搜索脑海中的知识,利用图书馆、网络等途径查阅资料,相互交流等多种渠道获取补充新内容,这无形中加深了对知识的理解,充分发挥学习主体自身的能动性,将知识转换为能力,这给自身的发展提供了上升的空间。
第二,促使学生养成独立思考的习惯,学生给出的解决方案都是经过独立思考、反复验证而得出的,几番讨论下来学生之间相互竞争,相互激励,从内心深处激发学生积极进取、刻苦学习的信心。
第三,多方交流,教学相长,在软件工程中测试人员和开发人员要相互避开,就是为了打破开发者的思维定势,从中找出破绽,完善软件功能,通过在课堂上讨论,验证,同学们可以提出自己的见解并质疑现有方案,本身就是一个相互交流,相互提高的过程。课堂讨论是教师直接管理案例教学的重要阶段,笔者认为针对待解决的问题让学生各抒己见,求大同、存小异,通过具体的代码验证来挑选最佳的实现方案,让学生体会到成功喜悦的同时引入下一个问题,让学生的大脑持续处于新鲜兴奋的状态,调动其学习的积极性。实践证明,随着案例教学的深入,解决问题的周期在逐渐缩短,这表明学生自主寻求理论知识来支撑论点的能力和拓展思维的能力均得到了提高。
通过该案例的制作,让学生们很好地掌握了.net平台窗体设计程序的全过程,约700多行的代码阅读、代码改错、规范化检查,引领学生体验程序员的职业生涯。在此基础上,提出新思考方向:得到文件路径和名称是完成管理文件的第一步,那如何利用.net框架提供的System.IO命名控件中的文件操作类实现路径的后退、前进、向上,如何对文件剪切、复制和粘贴等编辑操作和读取、写入、查看属性等操作呢?[5]有了新的思考方向,鼓励学生大胆想象设计、查阅资料、编写代码、运行查错、提出解决思路和可行性的实施方案,让学生反复提炼、归纳总结自己的经验,有了这个成功的教学案例,今后可在高职层次《C#程序设计》案例化教学进程中走得更远。
参考文献:
[1][3][4]资源管理器 [EB/OL].CSDN网站, http://download.csdn.net/detail/ZhengZhiRen/1013102.
[2]王平华.C#.NET程序设计项目教程[M].北京:中国铁道出版社,2008.
[5]杨学全.C#技术基础[M].北京:高等教育出版社,2008.