Sunday, 2 December 2018

arcobjects - Why is my OnChangeFeature event not firing in my parcel fabric editor extension?


I have an edit extension that listens to events that happen during an editor session. I have wired it like so:


void Events_OnStartEditing()

{

//Since features of shapefiles, coverages, and so on, cannot be validated, ignore wiring
//events for them.
if (ArcMap.Editor.EditWorkspace.Type !=
esriWorkspaceType.esriFileSystemWorkspace)
{
//Wire OnCreateFeature edit event.
Events.OnCreateFeature += new IEditEvents_OnCreateFeatureEventHandler
(Events_OnCreateFeature);

//Wire onChangeFeature edit event.
Events.OnChangeFeature += new IEditEvents_OnChangeFeatureEventHandler
(Events_OnChangeFeature);

}

}

The OnStartEditing event fires just fine. I want to listen for when an attribute from the row changes, so I wired an OnChangeFeature event:


void Events_OnChangeFeature(ESRI.ArcGIS.Geodatabase.IObject obj)

{
MessageBox.Show("Event fired");
}

Every time I go in and change a feature by editing the attribute table, this should fire. But it doesn't. I am manually editing features of the table (I'm not using a cursor to programatically update the features).


I will lastly mention that the feature class that I am editing is a subset of a parcel fabric. I'm not sure that this makes a difference as there is nothing in ESRI documentation that I have found that says that editing in a parcel fabric bypasses normal editing events, but I will mention it anyway.




EDIT: Ideas I have tried with no result:


Implementing IObjectClassInfo2 in my extension to make sure that no store methods are being bypassed:


public class ParcelEditorExtension : ESRI.ArcGIS.Desktop.AddIns.Extension, IObjectClassInfo2


public Boolean CanBypassStoreMethod()
{
return false;
}

public Boolean CanBypassEditSession()
{
return false;
}


Running the IWorkspaceEditControl.SetStoreEventsRequired() method to enforce this rule over the entire edit session.


IWorkspaceEditControl EditControl = ArcMap.Editor.EditWorkspace as IWorkspaceEditControl;
EditControl.SetStoreEventsRequired();



EDIT 2: It appears that the parcel fabric is, in fact, the issue. The event fires just fine when working on simple feature classes. Regardless, setting CanBypassStoreMethod() to false should fix this issue - is my implementation of this method correct?



Answer



The answer is because you are editing in a parcel fabric. When editing in a parcel fabric, the OnCreateFeature and OnChangeFeature events do not fire. No explanation is given in ESRI documentation for why this is the case, but I suspect that it has to do with parcels being edited through a job XML stream.


You aren't the only one to have this issue. See this mirror of a now-deleted (for inactivity) GIS.SE post of someone with the exact same issue.



No, setting CanBypassStoreMethod() does not fix the issue. Yes, this should be in ESRI's documentation somewhere that this event does not fire when working on cadastral/parcel fabrics, as well as some sort of workaround.


There are events available within the parcel table interfaces that fire when working within a parcel editing window (OnStartParcelEditing, OnJoin, job events, etc) but if someone edits an attribute table without opening this window, they will not fire. We want an event that fires if any changes are made to the attribute table whatsoever, so the aforementioned events do not fully encapsulate this action.


The answer is to get these changes from an edit operation. All ArcMap editor session edits are encapsulated in an edit operation. The events that fire whenever you add a feature or make an edit to the attribute table (from ESRI documentation) are as follows:



  1. OnStartOperation event fired

  2. OnChangeFeature/OnCreateFeature event fired

  3. BeforeStopOperation event fired

  4. OnStopOperation event fired


I discovered that in a parcel fabric, the OnChangeFeature (or OnCreateFeature if you are adding a parcel) does not fire, but the other three events do. So we can listen to BeforeStopOperation, which happens after the edit is complete but before the edit is saved. Wire your event handler for this, and also declare an IWorkspaceEdit2 for use later:



 private IWorkspaceEdit2 WorkspaceEdit;

void Events_OnStartEditing()
{
if (ArcMap.Editor.EditWorkspace.Type !=
esriWorkspaceType.esriFileSystemWorkspace)
{
//wire BeforeStopOperation editing event
Events2.BeforeStopOperation += new IEditEvents2_BeforeStopOperationEventHandler
(Events2_BeforeStopOperation);

WorkspaceEdit = (IWorkspaceEdit2)ArcMap.Editor.EditWorkspace;
}

}

Now that we wired the event, whenever it fires we need to get the changes. In your OnStopOperation event get IDataChangesEx from your IWorkspaceEdit2. IDataChangesEx holds not only the changed objects from within the edit operation but other various objects that give you pretty much all the freedom you want to manipulate them:


void Events2_BeforeStopOperation()
{

IDataChangesEx dataChanges = WorkspaceEdit.get_EditDataChanges(esriEditDataChangesType.esriEditDataChangesWithinOperation);

ESRI.ArcGIS.esriSystem.IEnumBSTR classes = dataChanges.ModifiedClasses;
string changedClass = classes.Next();
MessageBox.Show(changedClass);
if (changedClass == "GISDEV.DBO.PARCELFABRIC_PARCELS")
{
if (ParcelTable == null)
{
ParcelTable = parcelGateway.get_ParcelTable(out ParcelTable);
}
parcelGateway.ValidateParcelAttributes(changedClass, dataChanges, ParcelTable);

}

This should work with both versioned and unversioned parcel fabrics.


One unexplainable issue I encountered in this implementation is that it does not work in file geodatabases. IWorkspaceEdit.get_Editdatachanges() was returning null. The code works just fine in an SDE environment, however.


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...