Otra de las características que se ha mejorado sustancialmente en WSS3 son los eventos, ahora podemos asociarlos a cualquier tipo de lista, sitio o un item en concreto, el SDK nos ofrece un tipo de receptor de eventos para cada uno de ellos, por el momento (y como estamos hablando de una del SDK) las clases son Microsoft.SharePoint.SPItemEventReceiver, Microsoft.SharePoint.SPListEventReceiver y Microsoft.SharePoint.SPWebEventReceiver
Los eventos tienen dos formas, la que esta en pasado que se llevará acabo cuando el evento ya se ha producido, es decir después y la continua que se llevará acabo antes de que el evento ocurra. Con todo esto, disponemos de los siguientes eventos:
SPItemEventReceiver |
SPListEventReceiver |
SPWebEventReceiver |
ItemAdded |
FieldAdded |
SiteDeleted |
ItemAdding |
FieldAdding |
SiteDeleting |
ItemAttachmentAdded |
FieldDeleted |
WebDeleted |
ItemAttachmentAdding |
FieldDeleting |
WebDeleting |
ItemAttachmentDeleted |
FieldUpdated |
WebMoved |
ItemAttachmentDeleting |
FieldUpdating |
WebMoving |
ItemCheckedIn |
|
|
ItemCheckedOut |
|
|
ItemCheckingIn |
|
|
ItemCheckingOut |
|
|
ItemDeleted |
|
|
ItemDeleting |
|
|
ItemFileConverted |
|
|
ItemFileMoved |
|
|
ItemFileMoving |
|
|
ItemUncheckedOut |
|
|
ItemUncheckingOut |
|
|
ItemUpdated |
|
|
ItemUpdating |
|
|
De manera que si deseamos realizar eventos para los elementos de una lista, usaremos la clase base SPItemEventReceiver e iremos sobrescribiendo aquellos métodos que deseemos controlar.
public class MiEventHandler : SPItemEventReceiver
{ …. }
Por ejemplo si tenemos una lista que llamaremos demo y queremos que al añadir un elemento nos indique en un campo datos que es un elemento nuevo, y que siempre que se modifique un elemento nuevo en dicha lista el campo nuevo pase a contener modificado, y por último que no se pueda eliminar ningún elemento de dicha lista sin que previamente se haya modificado.
Deberemos sobrescribir, ItemAdded, ya que lo que pretendemos es modificar el contenido de un campo llamado datos una vez añadido un elemento para que tome el valor «Nuevo».
public override void ItemAdded(SPItemEventProperties properties)
{
SPListItem listItem = properties.ListItem;
listItem[«Datos»] = «Nuevo « + properties.EventType.ToString();
DisableEventFiring();
listItem.Update();
EnableEventFiring();
}
Cada uno de los eventos recibe información sobre el evento en por medio de SPItemEventProperties, como el tipo de evento (lo he añadido también en nuestro campo Datos, para que se vea claramente que acción ha realizado cada uno de los eventos, usando properties.EventType.ToString() ), el usuario que lo esta llevando acabo, el item de la lista que se esta tratando etc…. Es importante destacar en SPItemEventProperties, que a través de el recibimos información y también devolvemos información.
Usando SPItemEventProperties.BeforeProperties y SPItemEventProperties.AfterProperties, podemos obtener información sobre como estaba la lista antes y después de que se produzca el evento, y a través de la SPItemEventProperties.Cancel y SPItemEventProperties.Error podemos cancelar un evento y devolver un mensaje de error.
Durante la actualización del Item y dado que vamos a sobrescribir también ItemUpdated momentáneamente deshabilitaremos los eventos, de no hacerlo así al llamar a listItem.Update se lanzaría el evento ItemUpdated.
Como he dicho antes, ahora nos interesa controlar que cuando se edite por primera vez un elemento nuevo el campo de datos contenga «Modificado», por lo que ahora sobrescribiremos ItemUpdated, para que se vea quien ha realizado cada una de las acciones he añadido properties.EventType.ToString() .
public override void ItemUpdated(SPItemEventProperties properties)
{
SPListItem listItem = properties.ListItem;
if (listItem[«Datos»].ToString().Contains(«Nuevo»))
{
listItem[«Datos»] = «Modificado « + properties.EventType.ToString(); ;
listItem.Update();
}
}
Por último sobrescribiremos ItemDeleting, esta acción la queremos controlar antes de que se produzca el evento, ya que así podremos denegar el borrado.
public override void ItemDeleting(SPItemEventProperties properties)
{
SPListItem listItem = properties.ListItem;
if (listItem[«Datos»].ToString().Contains(«Nuevo»))
{
properties.Cancel = true;
properties.ErrorMessage = «No se puede eliminar un elemento Nuevo»;
}
}
Finalmente deberemos compilar nuestra biblioteca de clases, firmarla e instalarla en el GAC.
Para asociar nuestra biblioteca de eventos a una lista en particular, podemos escribir una pequeña aplicación de consola para realizar el trabajo o bien usar algo como este Event Handler Explorer de Patrick Tisseghem
using System;
using Microsoft.SharePoint;
namespace ConsoleTools
{
class Program
{
static void Main(string[] args)
{
SPSite site = new SPSite(«http://spsbeta/SiteDirectory/test»);
SPWeb web = site.OpenWeb();
SPList list = web.Lists[«Demo»];
string ensamblado = «MiWebPart, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d196fc71b3d34a48»;
string clase = «MiWebPart.MiEventHandler»;
list.EventReceivers.Add(SPEventReceiverType.ItemAdded, ensamblado, clase);
list.EventReceivers.Add(SPEventReceiverType.ItemUpdated, ensamblado, clase);
list.EventReceivers.Add(SPEventReceiverType.ItemDeleting, ensamblado, clase);
}
}
}
Básicamente abre un sitio web en busca de una lista y con la información del ensamblado vamos indicando que tipo de eventos son los que controlará nuestra biblioteca.
Creo que el cambio y las mejoras en los eventos de WSS3 tienen un potencial increíble para automatizar nuestros sitios.