EventHandler中需要注意的事件
项目中有个需求,需要一个列表联动九个其它列表,调试起来很费时间,也发现了EventHandler中的一些使用技巧,下面的内容大部分是转载,也有自己的心得,具体出处忘了,如果作者看到,请谅解。 
 
1. 在ItemAdding事件或ItemUpdating事件中获取用户输入的值
      通常我们都会遇到这样一个业务逻辑:只有当用户输入的值符合要求才允许用户添加记录,否则取消该操作;或者在用户添加一条记录时, 获取用户输入的值,再去进行其它操作。遇到这些业务,必须的是要在ItemAdding事件中获取到用户用户的值,那我们自然就会很想到一个属性properties.ListItem,这是正在添加的记录项,但恰恰这是添加前的事件,properties.ListItem的值为Null,并不能获取得到,就算在ItemUpdating事件中,properties.ListItem虽然是有值,但并不是用户输入的最新的值,而是原来的值(旧值),需要注意的是properties.BeforeProperties在Updating中也是无法取值的。
         想在记录项添加时或修改时得到新的值,我们可以直接使用下面的语句
 
properties.AfterProperties["Title"].ToString();
如果字段为汉字名,那就要取InternalName了,如下
 using (SPWeb web = (properties.OpenWeb()) as SPWeb)
                using (SPWeb web = (properties.OpenWeb()) as SPWeb) {
                { SPList List = web.Lists[properties.ListTitle] as SPList;
                    SPList List = web.Lists[properties.ListTitle] as SPList; sNameTitle = List.Fields["所属部门"].InternalName;
                    sNameTitle = List.Fields["所属部门"].InternalName; Orgname = properties.AfterProperties[sNameTitle].ToString();
                    Orgname = properties.AfterProperties[sNameTitle].ToString(); }
                }
2. 在ItemAdding事件或ItemUpdating事件中修改该记录项的值
         我们有时候在设计列表的时候,会添加一些对用户隐藏的栏,用于记录与该记录相关的信息,只能通过程序去改写此栏的值,那我们在添加新记录项或修改记录项时怎样修改该栏的值呢?
         很自然,我们会写出下面的程序
public override void ItemUpdating(SPItemEventProperties properties)
         {
             SPListItem item = properties.ListItem;
             item["Title"] = "这是我指定的值";
             item.Update();
         }
    但 很抱歉,运行这段的下场只有一个——出错!系统会报出“保存冲突”的错误信息。回头仔细看看代码,代码在记录项正在修改时,再次修改了该记录 项。与SQL相似,MOSS也会在进入ItemUpdating事件前,把该记录项上了锁,以防止该记录项在没完成本次修改前给再次修改,因此这样写注定 是失败的!如果是在ItemAdding事件更是如此,在前文说了,在ItemAdding事件时,properties.ListItem的值为Null,该记录项都还没生成,所以根本不可能也不应该通过properties.ListItem来修改某个栏上的值,因为properties.ListItem所表示的是一个记录项旧的值(新增前的旧值没是没有,null)
     那通过什么属性来修改呢?MOSS一定会提供一个途径给我们做这事的!我们再来关注一下properties.AfterProperties这个属性,从字面意思可以很容易知道,这是记录项新的值,但很可惜,这个属性是只读的,我们也不能直接修改这个属性达到我们的目的。接着往下看,在properties.AfterProperties中还有一个属性ChangedProperties,连起来看,properties.AfterProperties.ChangedProperties字面意思很 像是该属性保存该字段改变了的值(SDK也是这样说的,Gets properties that have changed in the collection),这很容易就理解成MOSS会自动比较用户修改了记录的哪些值,开始的时候,我也是这样理解的,但很奇怪,无论我怎样修改记录的 值,在调试时,该属性值的Count属性始终是0,并不如我开始所想的!
      那时在网上查了很多资料,都只是说奇怪MS为什么会提供ChangedProperties这样一个HashTable类型的属性,而且始终是没有值放到里面去的。在一次反编译MS的官方站点模板中的EventHandler事件程序时,我才恍然大悟!我们应该这样理解ChangedProperties这个HashTable,它是用于给我们修改栏值的一个集合,我觉得SDK的英文应该改成“Gets properties that will be changed in the collection”才对(个人见解),因为在ItemAdding事件或ItemUpdating事件中,记录项并没有真的生成或修 改,ListItem代表的是原来的值,AfterProperties代表的是这个记录项将要变成的值,共中的ChangedProperties提供再次修改的一次机会。所以,要在ItemAdding事件或ItemUpdating事件中修改该记录项的值得在这样写 
 using (SPWeb web = (properties.OpenWeb()) as SPWeb)
using (SPWeb web = (properties.OpenWeb()) as SPWeb) {
 { SPList List = web.Lists[properties.ListTitle] as SPList;   //取得当前修改的List
   SPList List = web.Lists[properties.ListTitle] as SPList;   //取得当前修改的List sNameTitle = List.Fields["组织编码"].InternalName;        //取得字段的名字
   sNameTitle = List.Fields["组织编码"].InternalName;        //取得字段的名字 string test01 = PItem["组织编码"].ToString();
   string test01 = PItem["组织编码"].ToString(); properties.AfterProperties.ChangedProperties.Add(sNameTitle, PItem["组织编码"]); //将修改的值赋给当前eventhandler的item
   properties.AfterProperties.ChangedProperties.Add(sNameTitle, PItem["组织编码"]); //将修改的值赋给当前eventhandler的item }
 }
注意事项: 
 
 在进行ItemUpdating,ItemAdding,ItemDeleting编程时,会有两个不同的动作,事件首先会锁定当前 ListItem,就是说你甭想改了,然后在Afterproperties中存放将要提交的修改值,这时你可以通过ChangeProperties来 修改这个将要提交的值,BeforeProperties这个比较奇怪,什么时候都取不到,基本上没用过。
 DisableEventFiring()及EnableEventFiring(),这是一组必要的方法,特别是在Updating和Updated事件中,但也要视具体情况而定,如果涉及到联动其它列表的,一般会DisableEventFiring()
 int Value1 = Convert.ToInt32(properties.AfterProperties[Field_InternalName].ToString());
 
 int Value2 = Convert.ToInt32(properties.BeforeProperties[Field_InternalName].ToString());
 
 properties.AfterProperties.ChangedProperties[Field_InternalName] = intInterval2;
 
 
尽量先确定前两个,再根据选择使用第三个. 此外如果前两点所述方法都报异常(在写ItemDeleting时会出现),那么则需要获得现在数据库里的值,可以这样做:
 try
 try {
 { String swhere = SyList.Fields["身份证号"].InternalName;
        String swhere = SyList.Fields["身份证号"].InternalName; String svalue = item["身份证号"].ToString();
        String svalue = item["身份证号"].ToString(); SyQry = new SPQuery();
        SyQry = new SPQuery(); SyQry.Query = "<Where><Eq><FieldRef Name='" + swhere + "'/><Value Type='Text'>" + svalue + "</Value></Eq></Where>";
        SyQry.Query = "<Where><Eq><FieldRef Name='" + swhere + "'/><Value Type='Text'>" + svalue + "</Value></Eq></Where>"; result = SyList.GetItems(SyQry);
        result = SyList.GetItems(SyQry); return result;
        return result; }
 } catch (Exception ex)
 catch (Exception ex) {
 { log.Error(ex.ToString());
   log.Error(ex.ToString()); throw ex;
   throw ex; }
 }  
 
                    
                
 
 
                 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号