RowCreatedEvent or RowChangedEvent

1335
6
10-30-2017 09:24 AM
MKa
by
Occasional Contributor III

I want to catch all Row Created and Row Changed events.  When i catch them, to have edit events based on which class was being edited.  However, i can't figure out where to subscribe at.  When i do the following in the Configuration Manager, ArcGIS Pro constantly says "Drawing".  In ArcObjects, i did all this work in an "Editor" extension I made that caught all of the Creates, Changes, and Deletes.  I think this is what i need, but I can't figure out where to put the subRowEvent?

protected override void OnApplicationInitializing(CancelEventArgs cancelEventArgs)
{
var theme = FrameworkApplication.ApplicationTheme;
//ApplicationTheme enumeration
if (FrameworkApplication.ApplicationTheme != ApplicationTheme.Dark)
{
//Dark theme
FrameworkApplication.ApplicationTheme = ApplicationTheme.Dark;
}

subRowEvent();
}

protected void subRowEvent()
{
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(onRowEvent, layerTable);
var rowChangeToken = RowChangedEvent.Subscribe(onRowEvent, layerTable);
var rowDeleteToken = RowDeletedEvent.Subscribe(onRowEvent, layerTable);
});
}

protected void onRowEvent(RowChangedEventArgs args)
{
Console.WriteLine("RowChangedEvent " + args.EditType.ToString());
}

Tags (1)
0 Kudos
6 Replies
MKa
by
Occasional Contributor III

So i was trying to subscribe in the Configuration Manager and not the Module like it is suppose to be.  i got the subscribe to work, but do i have to run this subscribe for every layer that I want to monitor change, create, and delete for?

protected override bool Initialize()
{
   subRowEvent();
   return base.Initialize();
}
#endregion Overrides


protected void subRowEvent()
{
   QueuedTask.Run(() =>
   {

      //This is where i need help getting all layers and add listener for each??

      foreach layer in layersList???

      {

            //Listen for row events on a layer
            var featLayer = layer as FeatureLayer;
            var layerTable = featLayer.GetTable();

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

      }      
   });
}

0 Kudos
MKa
by
Occasional Contributor III

Ok, i was able to subscribe to all of my layers using the code below to subscribe and unsubscribe using the tokens.  So i was able to catch when a new layer row was added, changed, or deleted.  The only problem is that some of the attributes for my feature layer are required by user input so they are not able to be created (so I get bad syntax in request).  Is there a way to set some attribute values before the row is actually created?  Before in ArcObjects, we were in an edit session, so onCreateFeature, I would set these values, but now it creates the Row first and then it fails before my code gets hit.  I need to set the values first, before the row gets added.

protected override bool Initialize()
{
   ActiveMapViewChangedEvent.Subscribe(OnActiveMapViewChanged);

   return base.Initialize();
}

protected override void Uninitialize()
{
   ActiveMapViewChangedEvent.Unsubscribe(OnActiveMapViewChanged);

   foreach (SubscriptionToken token in rowCreateTokens)
   {
      RowCreatedEvent.Unsubscribe(token);
   }

   

   foreach (SubscriptionToken token in rowChangeTokens)
   {
      RowChangedEvent.Unsubscribe(token);
   }

   foreach (SubscriptionToken token in rowDeleteTokens)
   {
      RowDeletedEvent.Unsubscribe(token);
   }
   base.Uninitialize();

}
#endregion Overrides


private async void OnActiveMapViewChanged(ActiveMapViewChangedEventArgs activeMapViewChangedEventArgs)
{
   await subscribeToRowEvent();
}

private static List<SubscriptionToken> rowCreateTokens = new List<SubscriptionToken>();
private static List<SubscriptionToken> rowChangeTokens = new List<SubscriptionToken>();
private static List<SubscriptionToken> rowDeleteTokens = new List<SubscriptionToken>();
protected Task subscribeToRowEvent()
{
   return QueuedTask.Run(() =>
   {

      if (MapView.Active != null && MapView.Active.Map != null)
      {
          var editLayers = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>();
            if (editLayers.Count() == 0)
               return;

            

              foreach (var layer in editLayers)
               {
                  //Listen for row events on a layer
                  var layerTable = layer.GetTable();

                  //subscribe to row events
                  SubscriptionToken rowCreateToken = RowCreatedEvent.Subscribe(onRowCreateEvent, layerTable);
                  SubscriptionToken rowChangeToken = RowChangedEvent.Subscribe(onRowChangeEvent, layerTable);
                  SubscriptionToken rowDeleteToken = RowDeletedEvent.Subscribe(onRowDeleteEvent, layerTable);

                  rowCreateTokens.Add(rowCreateToken);
                  rowChangeTokens.Add(rowChangeToken);
                  rowDeleteTokens.Add(rowDeleteToken);
              }
         }
   });
}

protected void onRowCreateEvent(RowChangedEventArgs args)
{
   Console.WriteLine("onRowCreateEvent " + args.EditType.ToString());
}

protected void onRowChangeEvent(RowChangedEventArgs args)
{
   Console.WriteLine("onRowChangeEvent " + args.EditType.ToString());
}

protected void onRowDeleteEvent(RowChangedEventArgs args)
{
   Console.WriteLine("onRowDeleteEvent " + args.EditType.ToString());
}

0 Kudos
by Anonymous User
Not applicable

Row events occur during the edit so you have the chance to cancel or change certain things carefully.

If I understand you correctly you want to change the value of an attribute on the row that's being created or modified?

In this case you can simply change the value through the row that's returned.

    private void onRowChangedEvent(RowChangedEventArgs obj)
    {
      var modRow = obj.Row;
      modRow["ZONING"] = "Mod";
    }

Rowevents are subscribed per event and per layer, so yes there is a bit of work to generically listen to all layers in a project. EditCompletedEvent is an alternative but that occurs after an edit has been completed without allowing you to change values.

Attributes rules will also be released with 2.1 allowing you to define actions that occur as features are modified, similar to attribute assistant in ArcMap.

MKa
by
Occasional Contributor III

My problem is, is that my RowChangedEvent or Row Created Event are never hit, because the row can't be inserted without a certain required attribute value being present.  I get the "Bad Syntax in request" in ArcGIS Pro, before any events even get hit.  The database requires 4 of my attributes be populated. Do i have to remove database constraints in order to use the feature service model?

Is there an event that is triggered before the RowCreated that I could prompt the user for values or modify the rows, much like we have done here for row created/changed.

0 Kudos
by Anonymous User
Not applicable

Were looking into a few things here. What constraints do you have on the fields?

There is no exposed event before the row is created. The other opportunity to change field values before the feature is created is by either manipulating the template field values, if the user is using a template to create features, or through the create methods on editoperation in the sdk.

MKa
by
Occasional Contributor III

We had some constraints on our database an ID and some other fields are required.  So when we tried to create the feature, Pro would signal an error as the insert wasn't allowed.  We removed the constraint now, as we will require the user to enter them, or we will auto enter them in the OnRowCreate event.  We also need to do this because the definition query uses certain attributes to determine what the user can see.  

Basically we are prompting a user with a dialog box whenever a new feature is created.  Before the dialog appears, we set some required attributes about their location.  The user then is required on the form to enter certain information.  They will not be able to close the form unless all required attributes are satisfied.  If they hit cancel on this new feature form, the feature is then deleted.

0 Kudos