现在在公司的一个项目中使用到AtlasToolkit中的CacadingDropDown,有一些需要有多选框(即Asp.Net服务器控件中的ListBox,HTML代码中的<select multiple="true"></select>),但是CascadingDropDown并不支持多选,全部是单选. 经过一翻研究和尝试之后,终于给它增加了多选的功能,于是就有了这篇文章.
AtlasToolkit中的控件由几个部分组成
- Bihavior:这是一个客户端Js文件,定义了控件在客户端的行为,应该是AtlasTookit控件的核心部分
- Extender:这是控件的服务端支持,用于支持控件的服务端操作
- Properties:这是服务端配置类
- Designer:设计时支持
在开始之前,先看看效果(注意最下一行字,这就是多选的结果),
要改造CascadingDropDown,就要拿这几个部分分别开刀.现在一步一步来.
第一步,使它在服务端支持ListBox
虽然多选框跟单选下拉框在客户端都是Select,但在服务端却是两个不同的控件.CascadingDropDown本身只支持DropDownList
public class CascadingDropDown : ExtenderControlBase<CascadingDropDownProperties, DropDownList>
上面是Extender文件中CascadingDropDown的声明,它继承自ExtenderControlBase,注意红色部分,因为这里的声明使它仅仅支持DropDownList,现在我们要把它改成ListControl,这样就可以同时支持ListBox和DropDownList了,因为这两个都继承自ListControl.
除了这里,Properties和Designer中的相应的泛型声明都要改成ListControl.
以上做的是在接口上支持ListBox,现在要使它在行为上支持ListBox.这个只需要改Extender一个文件就可以了.
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
foreach (CascadingDropDownProperties cascadingDropDownProperties in TargetProperties)
{
ListControl ctrl = (ListControl)FindControlHelper(cascadingDropDownProperties.TargetControlID);
if (ctrl is DropDownList)
{
DropDownList dropDownList = ctrl as DropDownList;
dropDownList.Items.Clear();
dropDownList.Items.Add(cascadingDropDownProperties.ClientState);
}
else if (ctrl is ListBox)
{
ListBox listBox = ctrl as ListBox;
listBox.Items.Clear();
if (cascadingDropDownProperties.ClientState == null)
return;
foreach (string item in cascadingDropDownProperties.ClientState.Split(','))
{
listBox.Items.Add(item);
}
}
}
}
protected override void OnPreRender(EventArgs e)
{
foreach (CascadingDropDownProperties cascadingDropDownProperties in TargetProperties)
{
ListControl ctrl = (ListControl)FindControlHelper(cascadingDropDownProperties.TargetControlID);
if (ctrl is DropDownList)
{
DropDownList dropDownList = ctrl as DropDownList;
dropDownList.Items.Clear();
}
else if (ctrl is ListBox)
{
ListBox listBox = ctrl as ListBox;
listBox.Items.Clear();
}
}
base.OnPreRender(e);
}
好了,上面就是改变服务端的,使之确实地支持ListBox,到这里服务端就修改完成了.
第二步,修改Behavior,以下的修改后的Behavior文件中的set_SelectedValue, 只需要修改这个地方就可以了.
this.set_SelectedValue = function(value) {
if( this.control != null && this.control.element != null && this.control.element.multiple )
{
var e = this.control.element;
//是多选框,即ListBox
_selectedValue = new Array();
for( var i = 0; i < e.options.length; ++i )
{
if( e.options[i].selected )
_selectedValue[ _selectedValue.length ] = e.options[i].value;
}
AtlasControlToolkit.CascadingDropDownBehavior.callBaseMethod(this, 'set_ClientState', [ _selectedValue.toString() ]);
}
else
{
_selectedValue = value;
AtlasControlToolkit.CascadingDropDownBehavior.callBaseMethod(this, 'set_ClientState', [ _selectedValue ]);
}
}
好了,编译,控件的发行就完成了.接下来说使用.
第一步:把ASPX文件中的DropDownList改成ListBox,并且加上SelectMode="Multiple"
第二步:使用类似以下的代码来取值
foreach (ListItem item in DropDownList3.Items)
{
//if (item.Selected)
color += RemoveValueText(item.Value) + ","
}
注意,我把红字部分,这一行是不需要的,因为传回来的所有Item都是被选中的,没有被选中的项并没有被传回来.
posted @
2006-08-26 11:28 Lupin 阅读(1472) |
评论 (6) |
编辑
tags: Asp.Net, ActionPack, Database, 数据库, CodeGeneration
昨天才知道有ActionPack这个东西,据介绍说很多概念是从Ruby On Rails来的,但我对Ruby On Rails没有了解,所以也不知道是怎样,但我知道ActionPack真是是相当强的东西,即使它现在还不是足够的强大,但是经过发展,必然大有作为.
闲话少说,到底ActionPack是个什么东西呢.说白了,它就是一个代码生成器,帮你生成访问数据库的代码. 但跟一般的代码生成器又有不同,ActionPack生成的代码并不存储在文件系统中,而是直接被编译在内存中,连Dll文件都没有.
它是怎么做到这些的呢?
最核心的就是BuildProvider了,它使用了Framework中的BuildProvider,在在生成的时候动态编译代码.这被编译的这些代码就是根据数据库中的表来生成的.而要让它做到这些,你只需要在配置文件中配置数据库连接字符串就可以了.
以上是感性的认识,接下来看看它的结构.
首先是一个BuildProvider,它继承自System.Web.Compilation.BuilderProvider,只要在Web.Config文件中配置,就可以让它在生成的时候直接运行里面的GenerateCode方法,跟HttpHandler有点类似.这是触发点.
然后是CodeGeneration,看名字就明白了,它用来生成代码.
然后是SchemaService,这个是用来读取数据库中的表信息的
TableSchema,存放表信息,在进行代码生成的时候使用到.
上面这几个,是ActionPack实现机制的主要部分.接下来的是一些配置和数据库访问的东西
ActionPackConfig,ActionPackConfigurationSetting,这两个是读取配置文件的,比较简单.
DBHelper和Query这两个是数据库操作的
ActiveList,ActiveRecord,这两上是Entry的模板类.在这里封装DBHelper和Query中的操作,使用这两个模板类,使生成的代码变得十分简单.否则,生成代码的工作将变得十分繁琐.
ActionPack的结构就这样了,有空再继续深入剖析.
posted @
2006-08-26 11:14 Lupin 阅读(180) |
评论 (1) |
编辑
This is a temporary post that was not deleted. Please delete this manually. (9c0ca929-af61-409a-ad8d-894d59464837)
posted @
2006-08-14 21:11 Lupin 阅读(81) |
评论 (0) |
编辑
发简历到这里,一方面想看看有没有朋友能给我提供暑假期间的实习。另一方面也想请大家指点一下,我这份简历有什么不足之处,应如何改进。谢谢!基于安全考虑,把手机号码和地址隐藏了。有实习工作推荐的话可以发邮件或者回复。PS:CSS乱了,有点乱,不好意思。
林XX (男 23岁)
- 网络工程
- 广东工业大学
- hillywolf@gmail.com
- xxxxxxx4747
- 020-3932xxxx
- 广州大学城广东工业大学
- 1984年11月
- 党员
个人概述
Dos时代接触电脑, 99年接触网络,01年接触编程,03年开始进行实际项目开发。不同程度掌握多种编程语言(C#,C/ C++, Java, Perl),具有大多同龄人没有的多个实际项目经验。在实际项目开发过程锻炼了程序开发能力,学习了UML,设计模式,单元测试等相关知识。
能使用Java 和 .Net 多个流行框架(如:Hibernate, Luence, Structs, Enterprise Library)等,并曾对其中部分的运行机制进行研究。从中学习到各种高效的设计方式,和优雅的编程习惯。
通过对专业课的学习,对计算机各层次原理有一定了解,有助于对高级语言更深地理解。
对计算机有浓厚兴趣和高度热情,乐于学习应用新知识。热爱工作,以成就感为最大的快乐源泉。
求职意向
希望能从事软件开发方面的工作。凭着几年的开发经验,可以从事C#,C/C++,Java方面的开发工作,尤其对C/C++的开发感兴趣!
主要项目经验
-
炽点搜索引擎优化系统(Asp.Net) 2005年4月-2006年6月
使用Visual Studio.Net开发,基于.Net 1.1,使用MSSQL数据库
一个用于网站访问统计的Web应用程序,除了一般的访问统计功能之外,它还具有追踪网站在被搜索引擎收录情况及排名,PageRank等变化的功能。还提供多种查看统计数据的方式,使用者可以方便的利用它所展示的数据对网站流量,搜索引擎优化情况进行分析。
负责系统设计和编码工作
使用Asp.Net1.1开发,大量使用了缓存技术
由于数据显示方式多,使数据表之间的耦合度较大,要进行大量的连接运行,而且数据量巨大,对数据库性能要求比较高。写出合适的SQL语句是最困难的工作。
后来得知这是一个数据仓库与商业智能的典型应用。这类应用的特点就是必须以空间换取效率。在该项目的数据库设计中,我适当了增加了数据冗余来减少数据表外部连接数量,以及降低SQL语句的复杂程度。
-
塔内网络管理系统(Asp.Net) 2005年7月-2006年2月
这是一个类似的OA的在线Web应用系统,包括人事管理,产品管理,业务管理三个主要模块。
参与需求分析,系统设计和编码工作,跟踪管理整个项目。
基于Enterprise Library,使用asp.net1.1进行开发。使用了UML来辅助需求调研和系统设计。
这 个项目中最大的难点是权限的控制。它不仅要求有功能的控制,还要求信息的控制。比如:主管具有审核注册成员的权限,而普通成员没有,这是功能控制;主管可 以查看本学校的所有业务信息,而普通成员只能查看自己的业务信息,区域主管可以查看本区域的业务信息。更困难的需求是,这一切都必须是可设置的,不能硬编 码。比如:可以在后台添加一个叫“主管”的角色,添加之后,可以修改该主管查看业务信息的范围,可以是区域级,学校级,或是仅仅查看自己的业务信息。因此 这个权限系统的设置必须十分细化。
在这个项目中使我收获最大的就是权限管理部分的设计。以下我的设计的概述。如下图,其中“范围”用于信息控制,“权限”用于功能控制,一个“权限项”对应一个功能。一个人员可以被任命为多个角色,同样的角色又可指定不同的范围,实现信息控制的需要。
-
vClass班级管理系统(Asp.Net) 2006年4月-2006年4月
一个面向班级的在线管理系统。类似于多班级的班级同学录,但功能更偏向于就读期间而非毕业之后,比如有作业发布,在线调查等功能。
完成除了界面设计之外的全部工作
使用asp.net1.1,基于Hibernate ORM框架开发,使用了许多现成组件,用以加快开发速度。
在需求上,这个项目并没有什么难点。它最大的难点在于时间要求非常紧,必须尽一切可能加快开发速度,同时又要保证质量
更深刻地理解了敏捷开发的思想。
教育背景
广东工业大学 2003年9月-2007年7月
网络工程 本科
C++程序设计,数据结构(c),操作系统原理,计算机系统结构,计算机接口,计算机组成原理,单片机基础,计算机网络,面向对象的思考过程,数据库系统原理及应用,线性代数,高等数学,离散数学,概率论与数理统计
在校信息
获奖记录
- 2004年2月 优秀学生干部
- 2004年5月 校社联周年庆积极分子
- 2004年12月 校网页设计大赛第二名
社会活动
- 曾任班长、校学生会科技实践部副部长
- 曾参与组织校园活动多次
- 曾任塔内网络科技有限公司广工业务主管
语言能力
普通话 惯用
广州话 能听/发音不准
英语四级 通过
英语六级 442分
posted @
2006-06-09 17:28 Lupin 阅读(1972) |
评论 (6) |
编辑
刚刚在看
Google Analytics,发现有从
Google黑板报过来的访问者,于是就过去看看是哪个页面链过来的。 让我发现
Google Toolbar4发布了的
消息。于是赶紧下下来试用了一下,发现增加了网页翻译的功能,还把
书签、
Blogger和
Gmail的部分功能整合进来了。
可惜,没把
Notebook和
Calendar也整合进来。最好能添加像MSN Toolbar那样的标签栏功能,那就比赛完美了。
posted @
2006-06-03 02:12 Lupin 阅读(123) |
评论 (0) |
编辑
中午在饭堂吃饭的时候电视上出现这么一句“让全社会都来关心大学生就业”。实在是相当搞笑,连大学生自己都不关心自己的就业问题,全社会关心又有什么用呢?
难道有人以为大学生关心自己的就业问题吗?如果关心的话就不会整天沉迷于玩乐,如果关心的话就不会大学毕业一无所获。四年时间,整个世界都可以被改变了,可是有些大学生除了把大学之前的东西忘掉了之外就没有任何收获了。难道这就是关心的表现吗?
有一句话说得好,“可怜之人必有可恨之处”,没错,这就是那些就业有问题的大学生的可恨之处。一个连对自己都不负责的人,不可恨吗?不值得同情,不值得关心。大学生都是成年人了,应该为自己的行为负责,造成无法就业的是他们自己,不是社会。如果一定要追究责任,那么另一个责任就来自于中国的高等教育体制了。
中国的基础教育体制是成功的(仅指知识方面),相信就平均知识储量来说,中国小孩的排名是占世界前几的。这是中国的基础教育体制决定的,强迫式的教育,升学的压力,中国的传统思想,无不强迫着小孩学习那些枯躁并且不知道有什么作用的知识。虽然并不理解,但是他们确实是掌握了。
相对于基础教育,中国的高等教育就是相当的失败了。由原来的严进宽出改为现在的宽进宽出更是最大的败笔。这个举动仅仅造就了一群高等学历的垃圾。宽松的生活环境,不严谨的治学环境无不证明中国高等教育的失败。在这样的环境之下,大学生在大学期间一无所获那也是情有原的了。
所以,中国应该首要关心的是“大学生教育”,而不应该是“大学生就业”,当“大学生教育”已经成功了,那时才是应该关心“大学生就业”的问题。
posted @
2006-05-31 12:34 Lupin 阅读(108) |
评论 (0) |
编辑
用了Google Analytics有一段时间了,都挺好的,不过有一点让我非常郁闷的,就是Google Analytics不认识Baidu作为一个搜索引擎。所以也就不会统计从Baidu过来的关键字,可是从Baidu到我的Blog来的访问相对是比较多的(虽然绝对来说,可以忽略。。。)
刚好前两天在博客园看到一篇
分析Google Analytics客户端代码的文章 看过之后,加上了一句
_uOsr[20]="baidu"; _uOkw[20]="wd";
嘿嘿,这样的就可以统计了来自Baidu的搜索了!
后来查了一下,发现,早已经有人发现了这个,而且不止添加了Baidu的,连什么3721,Yahoo等等很多搜索引擎都添加了,在
大名鼎鼎的车东那里。
_uOsr[20]="baidu"; _uOkw[20]="wd";
_uOsr[21]="3721"; _uOkw[21]="name";
_uOsr[22]="qq"; _uOkw[22]="w";
_uOsr[23]="yisou"; _uOkw[23]="p";
_uOsr[24]="sogou"; _uOkw[24]="query";
_uOsr[25]="iask"; _uOkw[25]="k";
_uOsr[26]="zhongsou"; _uOkw[26]="word";
_uOsr[27]="sina"; _uOkw[27]="_searchkey";
_uOsr[28]="163"; _uOkw[28]="q";
_uOsr[29]="soso"; _uOkw[29]="w";
_uOsr[30]="alexa"; _uOkw[30]="q";
posted @
2006-05-30 13:45 Lupin 阅读(107) |
评论 (0) |
编辑
刚刚终于知道怎么样在Word下发文章到Blog的时候同时上传图片了,只要填上Ftp的地址和目录,就会上传上去了,不过上传的时候还需要每次都输入用户名和密码。没错,真的上传上去了。以Png格式上传了。不过,显示的时候地址仍然是Ftp的地址,不是Http的地址,难道微软的工程师天真的以为在Http下的地址跟Ftp的地址是一样的吗?犯这么个低级错误,那真是相当的神奇!
相比之下,Performancing For Firefox就好得多了,填了Ftp地址,用户名、密码之后,还要设置一个HTTP访问地址。发布的时候将图片地址自动转换为Http地址了。
世上总是没有完美的东西。本来一个很完美的发布工具,却因为图片的关系变得很丑陋。
posted @
2006-05-29 23:36 Lupin 阅读(113) |
评论 (0) |
编辑
今天在做vClass的用户登录模块,用FormsAuthentication来进行用户登录处理的,用FormsAuthenticationTicket中的UserData来保存角色信息,可是,在测试的时候,保存在UserData中的信息总会不翼而飞,起初以为是Cookie没有正确更新的问题,于是单步调试,把每一步的Cookie字段都提出来进行比较,还是没有结果。最终决定求助于Google,用"g(FormsAuthenticationTicket UserData)"一搜就找到这篇文章了。原来,我也被.net“玩儿死了”。
在登录后进行页面跳转的时候使用FormsAuthentication.RedirectFromLoginPage(...)会导致UserData信息丢失,而用Response.Redirect( FormsAuthentication.GetRedirectUrl(..) )就不会了,Y滴,浪费了我一个中午的时间。
然后想起来,前段时间在试用magicajax的时候,文档中有写在config文件中设置 scriptPath=".."可以进行自定义JS文件的路径,在样就可以在里面写自己的代码。可是,怎么试也不成功,它还是引用默认的JS文件。后来,试着把scriptPath改成ScriptPath(S是大写),才总算能用了。。也被“玩儿死了”
posted @
2006-04-17 13:50 Lupin 阅读(127) |
评论 (0) |
编辑
在FxCop中建议代码中出现的某些字符串,比如Exception.Message这类的字符串不要直接写进代码中,而使用RescourceManager从资源文件中读取,这样做可以方便实现本地化。昨天花了好长时间,终于搞清楚应该怎么从资源文件中读值了。以下是记录。
首先,我们要有一个资源文件,就是.resx。创建的方法可以右击项目,选择添加新项,然后在资源文件夹中选 “程序集资源文件”,Ok。我们就得到一次资源文件了。在Vs中打开它可以很方便的进行编辑,其中比较重要的是name和value字段。它们的作用,不用我说,大家都知道了吧。
接下来就是重点了,使用RescourceManager从资源文件中读取值。以下是读取的关键的几句:
1 ResourceManager rm = new ResourceManager( "Lupin.vClass.Runtime.StringTable", Assembly.GetExecutingAssembly());
2 CultureInfo ci = Thread.CurrentThread.CurrentCulture;
3 string str = rm.GetString( name, ci );
重点在第一行中"Lupin.vClass.Runtime.StringTable", 还有 Assembly.GetExecuteingAssembly()。在这里,Lupin.vClass.Runtime是资源文件所在的项目的默认命名空间,最后一个单词StringTable就是文件名了。后面,Assembly.GetExecutingAssembly()的作用是取得当前正在执行的程序集,在这里的意义是资源文件所在的程序集。如果你读取的是其它程序集的资源文件,相应的这个要作改变。
后面,CultureInfo是本地信息,把它作为参数传递给GetString,程序能自动从相应的文件中读取值。比如用户的默认语言中是zh-cn,那么,程序在读取的时候会读取StringTable.zh-cn.resx中读取,相应的en-us的话,就会读取StringTable.en-us.resx,如果不传CultureInfo进去的话,那就是StringTable.resx了。
posted @
2006-04-15 16:36 Lupin 阅读(280) |
评论 (1) |
编辑