Event handlers for the Datasheet view
Due to some reasons, in very rare cases columns defined in a content type would lose their "required" status when updated via the "Datasheet view". So we needed a quick method to overcome this, and we decided to use event handlers for this purpose.
In this example, the code checks that the "StartDate" and "TaskDueDate" fields were filled out. Please note that for the -ing (synchronous) events, we must first check that the column is actually defined in the HashTable, and only afterwards check for its content. Not proceeding this way could lead to NullReferenceExceptions ... For the -ed (asynchronous) events, we can safely check for the column contents right from the start, as this event gets fired after the synchronous event. To be honest, these additional checks are not necessary, but were added as an additional precaution measure.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using Microsoft.SharePoint;
using System.Reflection;
using System.Collections;
namespace CUEvHandler {
public class TheEventHandler : SPItemEventReceiver {
// Adding event
// check if both fields are there, and the values are filled out
public override void ItemAdding(SPItemEventProperties properties) {
try {
bool correct1 = false;
bool correct2 = false;
foreach (DictionaryEntry dictionaryEntry in properties.AfterProperties) {
if (dictionaryEntry.Key.ToString() == "StartDate") // change Key name as necessary
if (dictionaryEntry.Value.ToString() != "")
correct1 = true;
if (dictionaryEntry.Key.ToString() == "TaskDueDate") // change Key name as necessary
if (dictionaryEntry.Value.ToString() != "")
correct2 = true;
}
if (!(correct1 && correct2)) {
// we cancel the addition, and mark the entry as invalid
properties.Cancel = true;
} }
catch (Exception ex) {
WriteTextToLog(ex.Message);
} }
// Added event
// this check is not really necessary, as it should never write to the log file
// still, written as a double-check measure
public override void ItemAdded(SPItemEventProperties properties) {
try {
if (properties != null)
if (properties.ListItem != null) {
bool ok = true;
if (properties.ListItem["Start Date"] == null) ok = false; // change index as necessary
if (properties.ListItem["Due Date"] == null) ok = false; // change index as necessary
if (!ok) {
String itemName = properties.ListItem.Name;
// you can indentify the element based on another property if necessary
WriteTextToLog("incorrect add! @ " + itemName);
} } }
catch (Exception ex) {
WriteTextToLog(ex.Message);
} }
// Updating event
// check if both fields are there, and the values are filled out
public override void ItemUpdating(SPItemEventProperties properties) {
try {
bool correct1 = false;
bool correct2 = false;
foreach (DictionaryEntry dictionaryEntry in properties.AfterProperties) {
if (dictionaryEntry.Key.ToString() == "StartDate") // change Key name as necessary
if (dictionaryEntry.Value.ToString() != "")
correct1 = true;
if (dictionaryEntry.Key.ToString() == "TaskDueDate") // change Key name as necessary
if (dictionaryEntry.Value.ToString() != "")
correct2 = true;
}
if (!(correct1 && correct2)) {
// we cancel the updating, and mark the entry as invalid
properties.Cancel = true;
} }
catch (Exception ex) {
WriteTextToLog(ex.Message);
} }
// Updated event
// this check is not really necessary, as it should never write to the log file
// still, written as a double-check measure
public override void ItemUpdated(SPItemEventProperties properties) {
try {
if (properties != null)
if (properties.ListItem != null) {
bool ok = true;
if (properties.ListItem["Start Date"] == null) ok = false; // change index as necessary
if (properties.ListItem["Due Date"] == null) ok = false; // change index as necessary
if (!ok) {
String itemName = properties.ListItem.Name;
// you can indentify the element based on another property if necessary
WriteTextToLog("incorrect add! @ " + itemName);
} } }
catch (Exception ex) {
WriteTextToLog(ex.Message);
} }
// logging procedure
// used by the Added / Updated events
// again, these can be left out and are for double-checking purposes only
private void WriteTextToLog(string logEntry) {
string filename = @"c:\listlog.txt";
// the path to the log file, should have r/w access to all users who edit the list!!!
StreamWriter logFile = File.AppendText(filename);
logFile.WriteLine(DateTime.Now.ToString() + ": " + logEntry);
logFile.Close();
} } }