Rez's Spot

Technical tips, suggestions and learnings on SharePoint.

Unable to add SharePoint event handler to the same list OnSaveChange() in a custom field type

  • Comments 1

I haven’t found any information on this but today I tried to add a custom event handler to a list automatically when a custom field type is added to a list using the OnSaveChange() method and I got the following error:

The specified program requires a newer version of Windows. (Exception from HRESULT: 0x8007047E)   at Microsoft.SharePoint.Library.SPRequestInternalClass.AddField(String bstrUrl, String bstrListName, String bstrSchemaXml, Int32 grfAdd) 
   at Microsoft.SharePoint.Library.SPRequest.AddField(String bstrUrl, String bstrListName, String bstrSchemaXml, Int32 grfAdd) 

This message doesn’t seem to be much help but what I think is happening is that SharePoint isn’t allowing simultaneous changes to a list using different SPWeb/SpSite objects.  Here is a break down of my problem:

  1. I created a custom field type that has custom configuration properties
  2. I created my own property edit control using the IFieldEditor Interface [1]
  3. Once the user hits OK to save the custom field to the list, it calls the OnSaveChange() method automatically
  4. In this OnSaveChange() method, I not only save my custom properties [2] but I also try to add an event handler to that same list using a new SPSite/SPWeb/SPList object [3].
  5. It throws the error above

The way I was able to fix this was that instead of creating my own SPSite/SPWeb and SPList objects use the SPField object that is passed to the OnSaveChange(SPField field, bool isNewField) method and accessing the list to be updated (with the event handler) by calling the field.ParentList object:

public void OnSaveChange(SPField field, bool isNewField)
{
try
{
SPSecurity.RunWithElevatedPrivileges(
delegate()
{
#region Delete Existing deleting event handlers first

SPEventReceiverDefinitionCollection evrs =
                       field.ParentList.EventReceivers;
List<Guid> ersToDelete = new List<Guid>();

foreach (SPEventReceiverDefinition er in evrs)
{
if (er.Type == SPEventReceiverType.ItemDeleting)
ersToDelete.Add(er.Id);
}

if (evrs.Count > 0)
{
foreach (Guid i in ersToDelete)
{
evrs[i].Delete();
field.ParentList.Update();
}
}

#endregion

string assembly = Assembly.GetExecutingAssembly().FullName;
string className = typeof(DeleteIconEventHandler).FullName;

field.ParentList.EventReceivers.Add(
                    SPEventReceiverType.ItemDeleting, assembly, className);
field.ParentList.Update();

});
}
catch (Exception ex)
{
string message = string.Format("ERROR: Method {0} had an exception while
            attempting RegisterDeleteItemEventHandler : {0}", ex.Message);
throw new SPException(message);
}
}

[1] http://msdn.microsoft.com/en-us/library/bb802857.aspx

[2] http://www.sharepointblogs.com/aaronrh/archive/2007/05/25/the-solution-to-saving-properties-in-custom-field-types.aspx

[3] http://fredmorrison.wordpress.com/category/uncategorized/

Leave a Comment
  • Yes need a new instance of the web and the list for each update is what other google entries are saying