ArcGIS Pro 3.4 API Reference Guide
ArcGIS.Desktop.Editing.Events Namespace / RowChangedEvent Class
Members Example Version

RowChangedEvent Class
Occurs when a Row is changed.
Object Model
RowChangedEvent ClassSubscriptionToken Class
Syntax
public static class RowChangedEvent 
Remarks
The RowChangedEvent is published during the execution of the edit operation. Any modifications performed within the RowEvent handler can cause cascaded events to be generated. Make sure you have an exit condition to avoid infinite recursion. For example, if you are changing a feature attribute within a RowCreatedEvent or RowChangedEvent, consider tracking that feature's objectID to ignore the corresponding RowChangedEvent your attribute change will generate.

If you need to edit additional tables within the RowEvent you MUST use the EditOperation that is passed through the RowChangedEventArgs. Do NOT use a new edit operation to create or modify features or rows in your RowEvent callback.

Example
Subscribe to Row Events
protected void SubscribeRowEvent()
{
  QueuedTask.Run(() =>
  {
    //Listen for row events on a layer
    var featLayer = MapView.Active.GetSelectedLayers().First() as FeatureLayer;
    var layerTable = featLayer.GetTable();

    //subscribe to row events
    var rowCreateToken = RowCreatedEvent.Subscribe(OnRowCreated, layerTable);
    var rowChangeToken = RowChangedEvent.Subscribe(OnRowChanged, layerTable);
    var rowDeleteToken = RowDeletedEvent.Subscribe(OnRowDeleted, layerTable);
  });
}

protected void OnRowCreated(RowChangedEventArgs args)
{
}

protected void OnRowChanged(RowChangedEventArgs args)
{
}

protected void OnRowDeleted(RowChangedEventArgs args)
{
}
Modify a record within Row Events - using Row.Store
private void HookRowChangedEvent()
{
  // subscribe to the RowChangedEvent
  Table table = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault().GetTable();
  RowChangedEvent.Subscribe(OnRowChangedEvent, table);
}

private Guid _currentRowChangedGuid = Guid.Empty;
protected void OnRowChangedEvent(RowChangedEventArgs args)
{
  // RowEvent callbacks are always called on the QueuedTask so there is no need 
  // to wrap your code within a QueuedTask.Run lambda.

  var row = args.Row;

  // check for re-entry  (only if row.Store is called)
  if (_currentRowChangedGuid == args.Guid)
    return;

  var fldIdx = row.FindField("POLICE_DISTRICT");
  if (fldIdx != -1)
  {
    //Validate any change to �police district�
    //   cancel the edit if validation on the field fails
    if (row.HasValueChanged(fldIdx))
    {
      // cancel edit with invalid district (5)
      var value = row["POLICE_DISTRICT"].ToString();
      if (value == "5")
      {
        //Cancel edits with invalid �police district� values
        args.CancelEdit($"Police district {row["POLICE_DISTRICT"]} is invalid");
      }
    }

    // update the description field
    row["Description"] = "Row Changed";

    //  this update with cause another OnRowChanged event to occur
    //  keep track of the row guid to avoid recursion
    _currentRowChangedGuid = args.Guid;
    row.Store();
    _currentRowChangedGuid = Guid.Empty;
  }
}
Modify a record within Row Events - using EditOperation.Modify
private void HookChangedEvent()
{
  // subscribe to the RowChangedEvent
  Table table = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault().GetTable();
  RowChangedEvent.Subscribe(MyRowChangedEvent, table);
}

private void MyRowChangedEvent(RowChangedEventArgs args)
{
  // RowEvent callbacks are always called on the QueuedTask so there is no need 
  // to wrap your code within a QueuedTask.Run lambda.

  //example of modifying a field on a row that has been created
  var parentEditOp = args.Operation;

  // avoid recursion
  if (_lastEdit != args.Guid)
  {
    //update field on change
    parentEditOp.Modify(args.Row, "ZONING", "New");

    _lastEdit = args.Guid;
  }
}
Determine if Geometry Changed while editing
private static FeatureLayer featureLayer;
private static void DetermineGeometryChange()
{
  featureLayer = MapView.Active?.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault();
  if (featureLayer == null)
    return;

  QueuedTask.Run(() =>
  {
    //Listen to the RowChangedEvent that occurs when a Row is changed.
    ArcGIS.Desktop.Editing.Events.RowChangedEvent.Subscribe(OnRowChangedEvent2, featureLayer.GetTable());
  });
}
private static void OnRowChangedEvent2(RowChangedEventArgs args)
{
  // RowEvent callbacks are always called on the QueuedTask so there is no need 
  // to wrap your code within a QueuedTask.Run lambda.

  //Get the layer's definition
  var lyrDefn = featureLayer.GetFeatureClass().GetDefinition();
  //Get the shape field of the feature class
  string shapeField = lyrDefn.GetShapeField();
  //Index of the shape field
  var shapeIndex = lyrDefn.FindField(shapeField);
  //Original geometry of the modified row
  var geomOrig = args.Row.GetOriginalValue(shapeIndex) as Geometry;
  //New geometry of the modified row
  var geomNew = args.Row[shapeIndex] as Geometry;
  //Compare the two
  bool shapeChanged = geomOrig.IsEqual(geomNew);
}
Inheritance Hierarchy

System.Object
   ArcGIS.Desktop.Editing.Events.RowChangedEvent

Requirements

Target Platforms: Windows 11, Windows 10

ArcGIS Pro version: 3 or higher.
See Also