通过上一篇文章WSS页面定制系列(2)---定制单个列表的表单页面您应该了解到了如何定制列表那些查看,新增,修改的页面。但是只限于页面布局。
如果需要修改保存逻辑应该怎么做呢?
     这个需求还是很常见的,比如,保存之前做一些校验,保存之后重定向到某个页面。
     系统模板里面负责保存操作的是如下的控件:
WSS页面定制系列(3)---重写表单的保存逻辑<SharePoint:SaveButton runat="server"/>
这个控件位于Microsoft.SharePoint.WebControls名称控件。我们用reflector找到关键代码:



SaveButton 控件也是采用模板实现的,它的模板如下
WSS页面定制系列(3)---重写表单的保存逻辑<SharePoint:RenderingTemplate ID="SaveButton" runat="server">
WSS页面定制系列(3)---重写表单的保存逻辑    
<Template>WSS页面定制系列(3)---重写表单的保存逻辑        <TABLE cellpadding=0 cellspacing=0 width=100%><TR><TD align="<SharePoint:EncodedLiteral runat='server' text='<%$Resources:wss,multipages_direction_right_align_value%>' EncodeMethod='HtmlEncode'/>"  width=100% nowrap>
WSS页面定制系列(3)---重写表单的保存逻辑          
<asp:Button UseSubmitBehavior="false" ID=diidIOSaveItem CommandName="SaveItem" Text="<%$Resources:wss,tb_save%>" class="ms-ButtonHeightWidth" accesskey="<%$Resources:wss,tb_save_AK%>" target="_self" runat="server"/>
WSS页面定制系列(3)---重写表单的保存逻辑        
</TD> </TR> </TABLE>
WSS页面定制系列(3)---重写表单的保存逻辑    
</Template>
WSS页面定制系列(3)---重写表单的保存逻辑
</SharePoint:RenderingTemplate>

    这里有一点有趣的东西,SaveButton利用了asp.net里面的事件冒泡机制,即子控件产生事件(就是那个CommandName="SaveItem"
的Button
),但并不处理,而是把事件“冒上去”,由父控件进行拦截处理(OnBubbleEvent方法)。
(既然是这样,我们用一个图片按钮来取代那个diidIOSaveItem应该也是可以的,只要ID和CommandName不变。)

言归正传---------------我第一次看到SaveButton控件的核心代码的时候,感到有点晕,太复杂了~ 而且,里面的很多内部方法都是私有的!
怎么改?
一种方法:继承SaveButton,重载OnBubbleEvent方法。对私有的方法,我们全部采用反射来调用。
这种方法其实是可行的,但是好像有一点“丑陋”。
第二种方法:我们是不是可以简化它的代码?我们重写的按钮只是用在有限的地方,不需要考虑的那么全面。

当我闷头探索第二种方法的时候,想到了第三种方法--我不要管它原来的代码,只接调用ListItem的Add方法不行吗?只要取到当前的所有字段,遍历即可。
取列表的所有字段,可以调用基类的 this.ItemContext.FormContext.FieldControlCollection类获得。

下面是实现代码:
WSS页面定制系列(3)---重写表单的保存逻辑using System;
WSS页面定制系列(3)---重写表单的保存逻辑using System.Collections.Generic;
WSS页面定制系列(3)---重写表单的保存逻辑using System.Text;
WSS页面定制系列(3)---重写表单的保存逻辑using System.Web;
WSS页面定制系列(3)---重写表单的保存逻辑using System.Web.UI.WebControls;
WSS页面定制系列(3)---重写表单的保存逻辑using System.Web.UI.HtmlControls;
WSS页面定制系列(3)---重写表单的保存逻辑
WSS页面定制系列(3)---重写表单的保存逻辑using Microsoft.SharePoint;
WSS页面定制系列(3)---重写表单的保存逻辑using Microsoft.SharePoint.Security;
WSS页面定制系列(3)---重写表单的保存逻辑using System.Web.UI;
WSS页面定制系列(3)---重写表单的保存逻辑 
WSS页面定制系列(3)---重写表单的保存逻辑using Microsoft.SharePoint.WebControls;
WSS页面定制系列(3)---重写表单的保存逻辑using System.Security.Permissions;
WSS页面定制系列(3)---重写表单的保存逻辑using Microsoft.SharePoint.Utilities
WSS页面定制系列(3)---重写表单的保存逻辑
WSS页面定制系列(3)---重写表单的保存逻辑namespace CodeArt.SharePoint
WSS页面定制系列(3)---重写表单的保存逻辑{
WSS页面定制系列(3)---重写表单的保存逻辑    /// 
<summary>
WSS页面定制系列(3)---重写表单的保存逻辑    /// 列表表单保存按钮,保存后返回本页面, 
WSS页面定制系列(3)---重写表单的保存逻辑    /// 
</summary>
WSS页面定制系列(3)---重写表单的保存逻辑    public class FormSaveButton : SaveButton
WSS页面定制系列(3)---重写表单的保存逻辑    {WSS页面定制系列(3)---重写表单的保存逻辑
WSS页面定制系列(3)---重写表单的保存逻辑        //return true stop event bubble
WSS页面定制系列(3)---重写表单的保存逻辑        //return false cotinue     
WSS页面定制系列(3)---重写表单的保存逻辑        protected override bool OnBubbleEvent(object source, EventArgs e)
WSS页面定制系列(3)---重写表单的保存逻辑        {
WSS页面定制系列(3)---重写表单的保存逻辑            this.Page.Validate();
WSS页面定制系列(3)---重写表单的保存逻辑
WSS页面定制系列(3)---重写表单的保存逻辑            if (!this.Page.IsValid)
WSS页面定制系列(3)---重写表单的保存逻辑            {
WSS页面定制系列(3)---重写表单的保存逻辑                return true ;
WSS页面定制系列(3)---重写表单的保存逻辑            }
               //some valid code
WSS页面定制系列(3)---重写表单的保存逻辑
WSS页面定制系列(3)---重写表单的保存逻辑            try
WSS页面定制系列(3)---重写表单的保存逻辑            {
WSS页面定制系列(3)---重写表单的保存逻辑                SaveData();
WSS页面定制系列(3)---重写表单的保存逻辑                return true ; 
WSS页面定制系列(3)---重写表单的保存逻辑            }
WSS页面定制系列(3)---重写表单的保存逻辑            catch (Exception ex)
WSS页面定制系列(3)---重写表单的保存逻辑            {               
WSS页面定制系列(3)---重写表单的保存逻辑                throw new SPException(ex.Message,ex);
WSS页面定制系列(3)---重写表单的保存逻辑            }
WSS页面定制系列(3)---重写表单的保存逻辑
WSS页面定制系列(3)---重写表单的保存逻辑Page.Response.Redirect("/");
WSS页面定制系列(3)---重写表单的保存逻辑
WSS页面定制系列(3)---重写表单的保存逻辑        }
WSS页面定制系列(3)---重写表单的保存逻辑
WSS页面定制系列(3)---重写表单的保存逻辑        void SaveData()
WSS页面定制系列(3)---重写表单的保存逻辑        {            
WSS页面定制系列(3)---重写表单的保存逻辑            SPListItem listItem;
WSS页面定制系列(3)---重写表单的保存逻辑
WSS页面定制系列(3)---重写表单的保存逻辑            if (this.ControlMode == SPControlMode.New)
WSS页面定制系列(3)---重写表单的保存逻辑                listItem = this.List.Items.Add();
WSS页面定制系列(3)---重写表单的保存逻辑            else
WSS页面定制系列(3)---重写表单的保存逻辑                listItem = this.ListItem;
WSS页面定制系列(3)---重写表单的保存逻辑
WSS页面定制系列(3)---重写表单的保存逻辑            foreach (BaseFieldControl f in this.ItemContext.FormContext.FieldControlCollection)
WSS页面定制系列(3)---重写表单的保存逻辑            {
WSS页面定制系列(3)---重写表单的保存逻辑                try
WSS页面定制系列(3)---重写表单的保存逻辑                {
                      //some valid code here --if(f.FieldName="XX") do something...

WSS页面定制系列(3)---重写表单的保存逻辑                    if (!f.Field.ReadOnlyField)
WSS页面定制系列(3)---重写表单的保存逻辑                        listItem[f.FieldName] = f.Value;
WSS页面定制系列(3)---重写表单的保存逻辑                }
WSS页面定制系列(3)---重写表单的保存逻辑                catch (ArgumentException) { }
WSS页面定制系列(3)---重写表单的保存逻辑            }
WSS页面定制系列(3)---重写表单的保存逻辑
WSS页面定制系列(3)---重写表单的保存逻辑            listItem.Update();   
WSS页面定制系列(3)---重写表单的保存逻辑        }     WSS页面定制系列(3)---重写表单的保存逻辑         
WSS页面定制系列(3)---重写表单的保存逻辑    }WSS页面定制系列(3)---重写表单的保存逻辑
WSS页面定制系列(3)---重写表单的保存逻辑}

这个FormSaveButton 的保存前后的行为可以由我们任意控制了。把它编译成dll,然后嵌入RenderingTemplate即可。

附:
SaveButton,FormField这类控件可以称为“表单控件”,它们实现对列表表单的操作,或者是呈现一个字段,后者是显示一个保存按钮,或者是来迭代生成页面。
它们的继承关系如下:

SaveButton 》 FormComponent 》 TemplateBasedControl》SPControl》 Control

FormField 》 BaseFieldControl 》 FieldMetadata》FormComponent
》 TemplateBasedControl 》SPControl》 Control

所有的“表单控件”都继承于TemplateBasedControl,都可以通过修改模板或重载替换已有控件来控制它的内容。











相关文章:

  • 2021-08-01
  • 2021-08-19
  • 2022-12-23
  • 2021-07-23
  • 2022-12-23
  • 2021-08-02
  • 2021-11-14
  • 2021-10-28
猜你喜欢
  • 2021-08-31
  • 2022-01-31
  • 2021-11-19
  • 2021-08-15
  • 2022-12-23
  • 2021-04-29
相关资源
相似解决方案