GithubHelp home page GithubHelp logo

Comments (6)

Wolf-K avatar Wolf-K commented on July 28, 2024

Hi Jeffrey,
Thanks for pointing this out. I was able to duplicate this scenario and will forward the issue to our development team.

from arcgis-pro-sdk-community-samples.

Wolf-K avatar Wolf-K commented on July 28, 2024

Hi Jeffrey,
After some closer examination of the issue I realized that many of our samples (including some in the Geodatabase topic) are updating the Geodatabase 'outside' the context of an edit operation. To duplicate your scenario I used a snippet that performed the update not in the context of the edit operation by using geodatabase calls like Row.Store or Row.UpdateAttachment. Please note that edits that are not performed with the 'EditOperation' context will not show up in the Save/Discard dialog nor will these updates be honored by the ArcGIS Pro UI. So in order for your edit to be 'part of' the EditOperation you need to use one of the patterns listed here:
https://github.com/Esri/arcgis-pro-sdk/wiki/ProSnippets-Editing and specifically when updating related tables or attachments here: https://github.com/Esri/arcgis-pro-sdk/wiki/ProSnippets-Editing#edit-operation-chain-edit-operations. If you used the EditOperation pattern in you programmatic update please provide me with the 'update' code snippet and I can take a further look.

Thanks, Wolf

from arcgis-pro-sdk-community-samples.

 avatar commented on July 28, 2024

Hi Wolf, please see below. This is just being called from the OnClick event of an addin command.

If you have time can you also check out this issue:
https://github.com/Esri/arcgis-pro-sdk/issues/9
and its related question for some background info:
https://geonet.esri.com/thread/195069-chaining-edit-operations

We are trying to figure out how much of the ArcMap workflow we can keep if we move to Pro. Currently it appears our methodology for recording edit history, asset sources, etc. doesn't have a "natural" fit in Pro.

Thanks!
Jeff

public void ProcessNewChainedEdits()
        {
            QueuedTask.Run(() =>
            {
                string message = string.Empty;
                bool processResult = false;

                var fl = MapView.Active.GetSelectedLayers().First() as FeatureLayer;
                if (fl.CanEditData())
                {
                    EditOperation eo = new EditOperation();
                    eo.ProgressMessage = "Inserting feature...";

                    try
                    {
                        ArcGIS.Core.Geometry.Coordinate2D c = new ArcGIS.Core.Geometry.Coordinate2D(1273229, 254577);
                        ArcGIS.Core.Geometry.MapPoint mp = ArcGIS.Core.Geometry.MapPointBuilder.CreateMapPoint(c.X, c.Y, MapView.Active.Map.SpatialReference);
                                              
                        var atts = new Dictionary<string, object>();
                                            
                        //Water.LEAK_PT SDE feature class                  
                        atts.Add("SHAPE", mp);
                        atts.Add("LEAK_WORKORDER_ID", "999444");

                        ////TestEdits fileGDB feature class
                        //atts.Add("SHAPE", mp);
                        ////atts.Add("StringField1", "999444");
                        //atts.Add("LongField1", 233232);
                 
                        eo.Create(fl, atts);

                        processResult = eo.Execute();

                        if (!processResult)
                        {
                            message = eo.ErrorMessage;
                            MessageBox.Show(message, "Feature Insert Error", MessageBoxButton.OK, MessageBoxImage.Error);
                        }

                        EditOperation eo2 = eo.CreateChainedOperation();
                        Geodatabase geodatabase = new Geodatabase(new DatabaseConnectionFile(new Uri("C:\\Users\\matsonj\\AppData\\Roaming\\ESRI\\Desktop10.4\\ArcCatalog\\dc_Water_spugisE.sde")));
                        Table eh = geodatabase.OpenDataset<Table>("EDIT_HISTORY");

                        var atts2 = new Dictionary<string, object>();
                        atts2.Add("EDTHSTR_KEY", 999998);
                        atts2.Add("EDTHSTR_FEATURE_KEY", "999888");

                        eo2.Create(eh, atts2);

                        bool pr2 = eo2.Execute();
                        if (!pr2)
                        {
                            MessageBox.Show(eo2.ErrorMessage, "Row Insert Error", MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                    catch (GeodatabaseException exObj)
                    {
                        message = exObj.Message;
                    }
                }
                else
                {
                    MessageBox.Show("Unable to edit data - check symbology");
                }
            });
        }

from arcgis-pro-sdk-community-samples.

SoJourned avatar SoJourned commented on July 28, 2024

Hi Jeff,

The code you have will be fine but I’ll try to expand on a few concepts.

In the following code im creating a point and writing to two stand alone tables, one in the same workspace as the point feature class and one external. This code is run through a button.
Because both table row creates are done through the same edit operation, the framework will maintain the undo/redo stack and save/discard. If you undo the operation, both records from the stand alone tables will also be removed.

    protected override void OnClick()
    {
      QueuedTask.Run(() =>
      {
        //create point in center of screen
        var featLayer = MapView.Active.Map.FindLayers("parcelpnt").FirstOrDefault() as FeatureLayer;
        var mp = MapView.Active.Extent.Center;
        var op = new EditOperation();
        op.Name = "Create point and external tables";
        op.Create(featLayer, mp);

        //create entry in table in the map
        var tab = MapView.Active.Map.FindStandaloneTables("EditHistory").First();
        var atts = new Dictionary<string, object>();
        atts.Add("Layer", "parcelpnt");
        atts.Add("Description", "EditOp: " + DateTime.Now.ToShortTimeString());
        op.Create(tab, atts);

        //create entry in different workspace
        var geodatabase2 = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(@"D:\temp\EditingWithArcGIS\Water.gdb")));
        var fgdbTable2 = geodatabase2.OpenDataset<Table>("eh2");
        op.Create(fgdbTable2, atts);

        op.Execute();
      });

In your code you didn’t need to chain the edit operation as you’re not doing anything from the first execute. However, since you probably want to record the OID of the feature that was created you would need chain the operation to write that value to the tables. Chaining the operation would look like the following:

    protected override void OnClick()
    {
      QueuedTask.Run(() =>
      {
        //create point in center of screen
        var featLayer = MapView.Active.Map.FindLayers("parcelpnt").FirstOrDefault() as FeatureLayer;
        var mp = MapView.Active.Extent.Center;
        var op = new EditOperation();
        op.Name = "Create point and external tables";
        long newFeatureID = -1;
        op.Create(featLayer, mp, oid => newFeatureID = oid);
        op.Execute();

        //create entry in table in the map
        var tab = MapView.Active.Map.FindStandaloneTables("EditHistory").First();
        var atts = new Dictionary<string, object>();
        atts.Add("Layer", "parcelpnt");
        atts.Add("Description", "OID: " + newFeatureID.ToString() + " " + DateTime.Now.ToShortTimeString());

        //chain to the first editop
        var opc = op.CreateChainedOperation();
        opc.Create(tab, atts);

        //create entry in different workspace
        var geodatabase2 = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(@"D:\temp\EditingWithArcGIS\Water.gdb")));
        var fgdbTable2 = geodatabase2.OpenDataset<Table>("eh2");
        opc.Create(fgdbTable2, atts);

        opc.Execute();
      });

So far this is ok for custom tools you develop but you could alternatively setup a generic listener for all edits, this is done through the three row events.
In the example below I’m listening for row changed on a parcel layer.

    protected override void OnClick()
    {
      QueuedTask.Run(() =>
      {
        //look for a layer named 'Parcels' in the map
        var featLayer = MapView.Active.Map.FindLayers("Parcels").FirstOrDefault() as FeatureLayer;
        if (featLayer == null)
          return;
        var layerTable = featLayer.GetTable();
        var rowChangedToken = RowChangedEvent.Subscribe(onRowChangedEvent, layerTable);
      });
      MessageBox.Show("Now listening to change events");
    }

    private void onRowChangedEvent(RowChangedEventArgs obj)
    {
      //update edit history table
      var sTable = MapView.Active.Map.FindStandaloneTables("EditHistory").First();
      var tab = sTable.GetTable();
      using (var rowbuff = tab.CreateRowBuffer())
      {
        rowbuff["Layer"] = "Parcels";
        rowbuff["Description"] = "OID: " + obj.Row.GetObjectID().ToString() + " " + DateTime.Now.ToShortTimeString();
        tab.CreateRow(rowbuff);
      }

      //update external table in a different workspace
      var geodatabase2 = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(@"D:\temp\EditingWithArcGIS\Water.gdb")));
      var fgdbTable2 = geodatabase2.OpenDataset<Table>("eh2");
      using (var rowbuff = fgdbTable2.CreateRowBuffer())
      {
        rowbuff["Layer"] = "Parcels";
        rowbuff["Description"] = "OID: " + obj.Row.GetObjectID().ToString() + " " + DateTime.Now.ToShortTimeString();
        fgdbTable2.CreateRow(rowbuff);
      }
    }

All edits done through the editor use an internal edit operation. Row events are called before this edit operation completes, giving you a chance to cancel the edit (RowChangedEventArgs.CancelEdit).
In this example since I don’t have access to that calling operation, Im using the Core.Data methods to write the two rows.
The catch here is, only rows that are in the same workspace as the calling edit operation will be managed by the framework. Since the first table (EditHistory in this example) is in the same workspace, the row will be managed and will be undone/redone etc with the application. For the second table, this is in an external workspace and while the row will still get written, it wont be managed, so for example if I discard edits the row will remain in that second table.

One thing we’ll do for 2.1 is open access to the calling edit operation in the row events. This means you should be able to piggy back additional operations onto the running edit operation and have the results managed by the framework. The resulting code will be something like:

    private void onRowChangedEvent2(RowChangedEventArgs obj)
    {
      var op = obj.Operation;
      if (op == null) return;

      //create entry in external table
      var geodatabase = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(@"D:\temp\EditingWithArcGIS\Montgomery_full.gdb")));
      var fgdbTable = geodatabase.OpenDataset<Table>("ExtHistory");
      op.Create(fgdbTable, atts);

      //create entry in different workspace
      var geodatabase2 = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(@"D:\temp\EditingWithArcGIS\Water.gdb")));
      var fgdbTable2 = geodatabase2.OpenDataset<Table>("eh2");
      op.Create(fgdbTable2, atts);
    }

You’ve mentioned a few times about parity between arcobjects and the pro sdk for your projects.
Can you be more specific about the editor events you used in ArcObjects and how you used them

Thanks
Sean

from arcgis-pro-sdk-community-samples.

 avatar commented on July 28, 2024

Hi Sean, thanks again for following up on this. If v2.1 provides something like your example for onRowChangedEvent2() we should be able to move forward. I'll update this thread as soon as we can get it installed, and have time to test it.

Jeff

from arcgis-pro-sdk-community-samples.

 avatar commented on July 28, 2024

At version 2.4 the OnRowChanged event now allows updates to tables from an external workspace.

The original issue (pending edits window) persists when a versioned table is the target. If the table is targeting Default it works fine.

from arcgis-pro-sdk-community-samples.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.