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

In This Topic
    RowChangedEvent Class
    In This Topic
    Occurs when a Row is changed.
    Object Model
    RowChangedEvent ClassSubscriptionToken Class
    Syntax
    public static class RowChangedEvent 
    Public MustInherit NotInheritable 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