如果需要修改保存逻辑应该怎么做呢?
这个需求还是很常见的,比如,保存之前做一些校验,保存之后重定向到某个页面。
系统模板里面负责保存操作的是如下的控件:
SaveButton 控件也是采用模板实现的,它的模板如下 :
这里有一点有趣的东西,SaveButton利用了asp.net里面的事件冒泡机制,即子控件产生事件(就是那个CommandName="SaveItem"
的Button),但并不处理,而是把事件“冒上去”,由父控件进行拦截处理(OnBubbleEvent方法)。
(既然是这样,我们用一个图片按钮来取代那个diidIOSaveItem应该也是可以的,只要ID和CommandName不变。)
言归正传---------------我第一次看到SaveButton控件的核心代码的时候,感到有点晕,太复杂了~ 而且,里面的很多内部方法都是私有的!
怎么改?
一种方法:继承SaveButton,重载OnBubbleEvent方法。对私有的方法,我们全部采用反射来调用。
这种方法其实是可行的,但是好像有一点“丑陋”。
第二种方法:我们是不是可以简化它的代码?我们重写的按钮只是用在有限的地方,不需要考虑的那么全面。
当我闷头探索第二种方法的时候,想到了第三种方法--我不要管它原来的代码,只接调用ListItem的Add方法不行吗?只要取到当前的所有字段,遍历即可。
取列表的所有字段,可以调用基类的 this.ItemContext.FormContext.FieldControlCollection类获得。
下面是实现代码:
//some valid code
//some valid code here --if(f.FieldName="XX") do something...
这个FormSaveButton 的保存前后的行为可以由我们任意控制了。把它编译成dll,然后嵌入RenderingTemplate即可。
附:
SaveButton,FormField这类控件可以称为“表单控件”,它们实现对列表表单的操作,或者是呈现一个字段,后者是显示一个保存按钮,或者是来迭代生成页面。
它们的继承关系如下:
SaveButton 》 FormComponent 》 TemplateBasedControl》SPControl》 Control
FormField 》 BaseFieldControl 》 FieldMetadata》FormComponent 》 TemplateBasedControl 》SPControl》 Control
所有的“表单控件”都继承于TemplateBasedControl,都可以通过修改模板或重载替换已有控件来控制它的内容。