Listening to object class events


Summary The IObjectClassEvents interface exposes several events that event handlers can listen to, allowing custom applications and extensions to respond to object creation, deletion, and modification. This topic explains how to use handlers for these events to store creation and modification dates for each object in an object class.

In this topic


About object class events

The IObjectClassEvents interface allows listeners to subscribe to events from an object class. These events occur when an object in the object class is created, deleted, or modified. This interface is implemented by several classes, including ObjectClass and FeatureClass.
There are two distinct ways of using the IObjectClassEvents interface: implementing the interface on a class extension or adding handlers to the IObjectClassEvents interface of an object class. This topic only applies to the latter; for information on the former, see Creating class extensions.
IObjectClassEvents publishes the following events:
A common practice for implementing object class event handlers is to create a class dedicated to listening to events (an event listener).
Listeners of the OnCreate event are not necessarily notified every time an object is created. The event is triggered following a call to IRow.Store, and by default this does not occur when objects or simple features are created using an insert cursor. If an event listener defines application-critical behavior in its OnCreate event handler, this default behavior can be overridden by setting the IWorkspaceEditControl.SetStoreEventsRequired method to true.

Creating an event handler

An event handler is a method within an event listener that defines the application's behavior in response to an event. Event handlers must match the return type and parameter types of the published events but can be given any name. The following code shows event handlers for the OnCreate and OnChange events that modify "created" and "modified" date fields:
[C#]
public void OnCreate(IObject createdObject)
{
    // Set the creation date to Now. Note that Store() is not needed.
    createdObject.set_Value(createdFieldIndex, DateTime.Now);
}

public void OnChange(IObject changedObject)
{
    // Set the modification date to Now. Note that Store() is not needed.
    changedObject.set_Value(modifiedFieldIndex, DateTime.Now);
}
[VB.NET]
Public Sub OnCreate(ByVal createdObject As IObject)
    ' Set the creation date to Now. Note Store() is not needed.
    createdObject.Value(createdFieldIndex) = DateTime.Now
End Sub

Public Sub OnChange(ByVal changedObject As IObject)
    ' Set the modification date to Now. Note Store() is not needed.
    changedObject.Value(modifiedFieldIndex) = DateTime.Now
End Sub
These code examples do not call Store() on the objects being passed in as parameters. If other objects are modified, however—for example, related objects or connected network features—call Store() on those objects.

Adding handlers to events

Adding a handler to an event varies slightly between C# and VB. NET.
In C#, an instance of the event's delegate type must be created to encapsulate the event handler. The delegate is instantiated much like a class, by using the new keyword. In VB. NET, the AddressOf operator is used to create a procedure delegate for the method. The delegate instance can then be added to the appropriate event on the event interface. In C#, the += operator is used; in VB. NET, the AddHandler statement is used.
The following code example is an event listener's constructor, which instantiates two different delegates and adds them to the respective events of the object class' event interface. To tightly couple an event listener with an object class, the event listener's constructor can accept an IObjectClass parameter, then cast it to the event interface.
[C#]
public ObjectClassEventListener(IObjectClass objectClass, int createdFieldIndex, int
    modifiedFieldIndex)
{
    // Cast the object class to the event interface.
    IObjectClassEvents_Event objectClassEvent = (IObjectClassEvents_Event)
        objectClass;

    // Instantiate the delegate types and add them to the events.
    objectClassEvent.OnCreate += new IObjectClassEvents_OnCreateEventHandler
        (OnCreate);
    objectClassEvent.OnChange += new IObjectClassEvents_OnChangeEventHandler
        (OnChange);

    // Store the index parameters in member variables.
    this.createdFieldIndex = createdFieldIndex;
    this.modifiedFieldIndex = modifiedFieldIndex;
}
[VB.NET]
Public Sub New(ByVal objectClass As IObjectClass, ByVal createdFieldIndex As Integer, ByVal modifiedFieldIndex As Integer)
    ' Cast the object class to the event interface.
    Dim objectClassEvent As IObjectClassEvents_Event = CType(objectClass, IObjectClassEvents_Event)
    
    ' Create procedure delegates and add them to the events.
    AddHandler objectClassEvent.OnCreate, AddressOf OnCreate
    AddHandler objectClassEvent.OnChange, AddressOf OnChange
    
    ' Store the index parameters in member variables.
    Me.createdFieldIndex = createdFieldIndex
    Me.modifiedFieldIndex = modifiedFieldIndex
End Sub

Instantiating a listener

Once the listener is completed, it can be used in custom applications. Instantiating a listener is simple, as shown in the following code example:
[C#]
// Open the cities feature class and cast to IObjectClass.
IFeatureClass featureClass = featureWorkspace.OpenFeatureClass("Can_Mjr_Cities");
IObjectClass objectClass = (IObjectClass)featureClass;

// Find the created and modified field indexes.
int createdFieldIndex = featureClass.FindField("Created");
int changedFieldIndex = featureClass.FindField("Changed");

// Create an event handler.
ObjectClassEventListener eventListener = new ObjectClassEventListener(objectClass,
    createdFieldIndex, changedFieldIndex);
[VB.NET]
' Open the cities feature class and cast to IObjectClass.
Dim featureClass As IFeatureClass = featureWorkspace.OpenFeatureClass("Can_Mjr_Cities")
Dim objectClass As IObjectClass = CType(featureClass, IObjectClass)

' Find the created and modified field indexes.
Dim createdFieldIndex As Integer = featureClass.FindField("Created")
Dim changedFieldIndex As Integer = featureClass.FindField("Changed")

' Create an event handler.
Dim eventListener As ObjectClassEventListener = New ObjectClassEventListener(objectClass, createdFieldIndex, changedFieldIndex)

Completing listener implementation

The following code example shows the full implementation of the event listener described in this topic:
[C#]
public class ObjectClassEventListener
{
    // Member variables for field index storage.
    private int createdFieldIndex =  - 1;
    private int modifiedFieldIndex =  - 1;

    public ObjectClassEventListener(IObjectClass objectClass, int createdFieldIndex,
        int modifiedFieldIndex)
    {
        // Cast the object class to the event interface.
        IObjectClassEvents_Event objectClassEvent = (IObjectClassEvents_Event)
            objectClass;

        // Instantiate the delegate types and add them to the events.
        objectClassEvent.OnCreate += new IObjectClassEvents_OnCreateEventHandler
            (OnCreate);
        objectClassEvent.OnChange += new IObjectClassEvents_OnChangeEventHandler
            (OnChange);

        // Store the index parameters in member variables.
        this.createdFieldIndex = createdFieldIndex;
        this.modifiedFieldIndex = modifiedFieldIndex;
    }

    public void OnCreate(IObject createdObject)
    {
        // Set the creation date to Now. Note that Store() is not needed.
        createdObject.set_Value(createdFieldIndex, DateTime.Now);
    }

    public void OnChange(IObject changedObject)
    {
        // Set the modification date to Now. Note that Store() is not needed.
        changedObject.set_Value(modifiedFieldIndex, DateTime.Now);
    }
}
[VB.NET]
Public Class ObjectClassEventListener
    ' Member variables for constructor parameter storage.
    Dim objectClass As IObjectClass = Nothing
    Dim createdFieldIndex As Integer = -1
    Dim modifiedFieldIndex As Integer = -1
    
    Public Sub New(ByVal objectClass As IObjectClass, ByVal createdFieldIndex As Integer, ByVal modifiedFieldIndex As Integer)
        ' Cast the object class to the event interface.
        Dim objectClassEvent As IObjectClassEvents_Event = CType(objectClass, IObjectClassEvents_Event)
        
        ' Create procedure delegates and add them to the events.
        AddHandler objectClassEvent.OnCreate, AddressOf OnCreate
        AddHandler objectClassEvent.OnChange, AddressOf OnChange
        
        ' Store the index parameters in member variables.
        Me.createdFieldIndex = createdFieldIndex
        Me.modifiedFieldIndex = modifiedFieldIndex
    End Sub
    
    Public Sub OnCreate(ByVal createdObject As IObject)
        ' Set the creation date to Now. Note Store() is not needed.
        createdObject.Value(createdFieldIndex) = DateTime.Now
    End Sub
    
    Public Sub OnChange(ByVal changedObject As IObject)
        ' Set the modification date to Now. Note Store() is not needed.
        changedObject.Value(modifiedFieldIndex) = DateTime.Now
    End Sub

End Class


See Also:

How to wire ArcObjects .NET events




To use the code in this topic, reference the following assemblies in your Visual Studio project. In the code files, you will need using (C#) or Imports (VB .NET) directives for the corresponding namespaces (given in parenthesis below if different from the assembly name):
Development licensing Deployment licensing
ArcView ArcView
ArcEditor ArcEditor
ArcInfo ArcInfo
Engine Developer Kit Engine Runtime: Geodatabase Update